在表单验证过程中,相对ObjectDoesNotExist [英] RelatedObjectDoesNotExist during form validation

查看:307
本文介绍了在表单验证过程中,相对ObjectDoesNotExist的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个让我疯狂的问题



我有模型

  class Property1(CommonInfo):
unit = models.ForeignKey(Unit)
is_true = models.BooleanField(default = False)
propertytype = models.ForeignKey(Propertytype,related_name = propertytype')
date = models.DateTimeField(null = True,blank = True)
followup_date = models.DateTimeField(null = True,blank = True)
quantity = models.PositiveSmallIntegerField


def __str __(self):
return self.propertytype

def clean(self):
model = self .__ class__
if(self.unit)和model.objects.filter(unit = self.unit,propertytype = self.propertytype).exclude(id = self.id).count()== 1:
raise ValidationError('相同的属性不能被分配多于一个)

对于这个模型我有形式



  class Property1Form(forms.ModelForm):

class Meta:
model = Property1
fields = ['unit','propertytype','is_true','date','followup_date','quantity','description']

def __init __(self,* args,** kwargs):
super(Property1Form,self).__ init __(* args,** kwargs)
instance = getattr(self, 'instance',None)
如果实例:
self.fields ['unit']。required = False
self.fields ['unit']。widget.attrs ['disabled'] ='disabled'

我有一个视图



$ $ $ $ $ $ $ $ $ $单位= get_object_or_404(单位,pk = pk)
标题='财产'
uri = _get_redirect_url(request,uri)
如果request.method ==POST:
form = Property1Form(request.POST)
form.unit = unit


如果form.is_valid():
属性= form.save(commit = False)
property.unit = unit

properties.save()
messages.add_message(request,messages.SUCCESS,str(properties.unit)+-SUCCESS Object successfully sucssefully)

return redirect(uri)
else:
form = Property1Form(initial = {'unit':unit})


return render ,'object_edit.html',{'form':form,'title':title,'extend':EXTEND})

但是,创建新的属性后,我总是得到


相关ObjectDoesNotExist在*** Property1没有单位。

执行

期间触发的错误

  if form.is_valid():

有什么问题?



更新:



追溯:

 文件 C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\\ core_\\handlers\base.pyin get_response 
132. response = wrapped_callback(request,* callback_args,** callback_kwargs)
文件C:\Users\Boris\dev\ property_new
390.如果form.is_valid():
文件C:\Users\Boris\dev\rentout\,则为rentout\rentout\unit\views.py is_valid
184.返回self.is_bound而不是self.errors
文件C:\Users\\中的virtrentout\lib\site-package\django\forms\forms.py错误
176. self.full_clean()
文件\\ Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\forms.py C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\forms.pyin full_clean
394. self._post_clean()
文件C:\Users\Boris\dev\rentout\virtrentout\lib\sit _post_clean中的e-packages\django\forms\models.py
430. self.instance.full_clean(exclude = exclude,validate_unique = False)
文件C:\Users\在full_clean
1132中的Boris\dev\rentout\virtrentout\lib\site- packages\django\db\models\base.py。self.clean()
文件C:\Users\Boris\dev\rentout\rentout\unit\models.py在clean
117. if(self.unit)和model.objects.filter(unit = self.unit,propertytype = self.propertytype).exclude(id = self.id).count()== 1:
文件C:\Users\Boris\dev\rentout\ __get__
608.%s没有%s中的virtrentout\lib\site-package\django\db\models\fields\related.py。 %(self.field.model .__ name__,self.field.name)

异常类型:RelatedObjectDoesNotExist at /unit/property/new/6/http://127.0.0.1:8000/unit/ property_details / 6 /
异常值:Property1没有单位。


解决方案

设置 required = False 并禁用窗口小部件并不理想。禁用窗口小部件意味着您的浏览器将不会为该字段提交任何值。因为你有 required = False ,这意味着表单将外键设置为 None 。但是,这与模型的外键不兼容,默认情况下它的外键为 null = False



不够熟悉的内部要精确地解释异常,但基本的问题是Django试图从数据库中获取相关的单元,表单设置外部$



一项工作是检查 self.unit_id 而不是 self.unit 。这样可以防止数据库查找,所以你没有得到例外。



然而,对我来说这似乎有点脏。如果您不希望用户编辑单位字段,我将完全从表单中删除它。检查 self.instance.pk 以确定实例是否在数据库中。

 $ _ $ _ $(self,* args,** kwargs):
super(Property1Form,self).__ init __(* args,** kwargs)
if self.instance.pk:
del self.fields ['unit']

然后在你看来,你应该'不得不再次设置 properties.unit = unit 。我会删除 form.unit = unit ,我不认为这是没有用的。


I have an issue that makes me crazy

I have model

class Property1(CommonInfo):
    unit = models.ForeignKey(Unit)
    is_true = models.BooleanField(default=False)
    propertytype = models.ForeignKey(Propertytype, related_name='propertytype')
    date = models.DateTimeField(null=True, blank=True)
    followup_date = models.DateTimeField(null=True, blank=True)
    quantity = models.PositiveSmallIntegerField()


    def __str__(self):
        return self.propertytype

    def clean(self):
        model = self.__class__
        if  (self.unit) and model.objects.filter(unit=self.unit, propertytype=self.propertytype ).exclude(id=self.id).count() == 1:
            raise ValidationError('Same property cant be assigned more then ones')

for this model I have form

class Property1Form(forms.ModelForm):

    class Meta:
        model = Property1
        fields = ['unit','propertytype','is_true','date','followup_date','quantity','description']

    def __init__(self, *args, **kwargs):
        super(Property1Form, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance:
            self.fields['unit'].required = False
            self.fields['unit'].widget.attrs['disabled'] = 'disabled'

And I have a view

def property_new(request,pk,uri):
    unit = get_object_or_404(Unit, pk=pk)
    title = 'property'
    uri = _get_redirect_url(request, uri)
    if request.method == "POST":
        form = Property1Form(request.POST)
        form.unit = unit


        if form.is_valid():
            properties = form.save(commit=False)
            properties.unit = unit 

            properties.save()
            messages.add_message(request, messages.SUCCESS, str(properties.unit) + "-SUCCESS Object created sucssefully")

            return redirect(uri)
    else:
        form = Property1Form(initial={'unit': unit})


    return render(request, 'object_edit.html', {'form': form, 'title':title, 'extend': EXTEND})

However, after creating new property I always get

RelatedObjectDoesNotExist at *** Property1 has no unit.

Error triggered during execution of

  if form.is_valid(): 

What is the problem?

UPDATE:

Traceback:

File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\core\handlers\base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Boris\dev\rentout\rentout\unit\views.py" in property_new
  390.         if form.is_valid():
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\forms.py" in is_valid
  184.         return self.is_bound and not self.errors
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\forms.py" in errors
  176.             self.full_clean()
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\forms.py" in full_clean
  394.         self._post_clean()
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\models.py" in _post_clean
  430.             self.instance.full_clean(exclude=exclude, validate_unique=False)
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\models\base.py" in full_clean
  1132.             self.clean()
File "C:\Users\Boris\dev\rentout\rentout\unit\models.py" in clean
  117.         if  (self.unit) and model.objects.filter(unit=self.unit, propertytype=self.propertytype ).exclude(id=self.id).count() == 1:
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\models\fields\related.py" in __get__
  608.                 "%s has no %s." % (self.field.model.__name__, self.field.name)

Exception Type: RelatedObjectDoesNotExist at /unit/property/new/6/http://127.0.0.1:8000/unit/property_details/6/
Exception Value: Property1 has no unit.

解决方案

Setting required=False and disabling the widget is not ideal. Disabling the widget means that your browser will not submit any values for that field. Since you have required=False, this means that the form will set the foreign key to None. However, this is incompatible with the model's foreign key, which has null=False by default.

I'm not familiar enough with the internals to precisely explain the exception, but the basic problem is that Django is trying to fetch the related unit from the database, after the form has set the foreign key to None.

One work around is to check self.unit_id rather than self.unit. This prevents the database lookup, so you don't get the exception.

However, this seems a bit dirty to me. If you don't want the user to edit the unit field, I would remove it from the form completely. Check self.instance.pk to determine whether or not the instance is in the database already.

def __init__(self, *args, **kwargs):
    super(Property1Form, self).__init__(*args, **kwargs)
    if self.instance.pk:
        del self.fields['unit']

Then in your view, you shouldn't have to set properties.unit = unit any more. I would remove form.unit = unit as well, I don't think it was ever useful.

这篇关于在表单验证过程中,相对ObjectDoesNotExist的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆