在表单验证过程中,相对ObjectDoesNotExist [英] RelatedObjectDoesNotExist during form validation
问题描述
我有一个让我疯狂的问题
我有模型
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屋!