为什么会发生 - 由Model.clean()引起的RelatedObjectDoesNotExist错误?

时间:2016-07-12 16:34:40

标签: python django

我有一个干净的方法,在我的模型文件中给出了RelatedObjectDoesNotExist错误

@with_author 
class BOMVersion(models.Model): 
    version = IntegerVersionField( )
    name = models.CharField(max_length=200,null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    material =  models.ForeignKey(Material)
    creation_time = models.DateTimeField(auto_now_add=True, blank=True)
    abovequantity = models.DecimalField(max_digits=19, decimal_places=10)
    belowquantity = models.DecimalField(max_digits=19, decimal_places=10)
    valid_from = models.DateTimeField(null=True, blank=True)
    valid_to = models.DateTimeField(null=True, blank=True)
    is_default = models.BooleanField(default=False)  





    def clean(self):
        model = self.__class__
        if model.objects.filter(material=self.material, is_default=True).count()  > 1:

            raise ValidationError('Material {} has a defaul value already'.format(self.material))

更新: 追溯

> Traceback: File
> "C:\Users\I812624\dev\mrp\lib\site-packages\django\core\handlers\base.py"
> in get_response
>   132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\I812624\dev\mrp\lib\site-packages\django\contrib\auth\decorators.py"
> in _wrapped_view
>   22.                 return view_func(request, *args, **kwargs) File "C:\Users\I812624\dev\mrp\src\item\views\viewsbomversion.py" in
> bomversion_new
>   68.         if form.is_valid(): File "C:\Users\I812624\dev\mrp\lib\site-packages\django\forms\forms.py" in
> is_valid
>   184.         return self.is_bound and not self.errors File "C:\Users\I812624\dev\mrp\lib\site-packages\django\forms\forms.py" in
> errors
>   176.             self.full_clean() File "C:\Users\I812624\dev\mrp\lib\site-packages\django\forms\forms.py" in
> full_clean
>   394.         self._post_clean() File "C:\Users\I812624\dev\mrp\lib\site-packages\django\forms\models.py" in
> _post_clean
>   430.             self.instance.full_clean(exclude=exclude, validate_unique=False) File
> "C:\Users\I812624\dev\mrp\lib\site-packages\django\db\models\base.py"
> in full_clean
>   1132.             self.clean() File "C:\Users\I812624\dev\mrp\src\item\models.py" in clean
>   673.         if model.objects.filter(material=self.material, is_default=True).count()  > 1: File
> "C:\Users\I812624\dev\mrp\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
> /item/bomversion/new/1/http://127.0.0.1:8000/item/material/material_bomversion_details/1/
> Exception Value: BOMVersion has no material.

看起来在清洁方法中看不到材料。 如果我从验证中删除材料并且只留下is_default字段,那就没关系。

我无能为力.....

更新:

问题可能是材料价值不是来自表格而是在视图中填充

 if form.is_valid():
            bomversion= form.save(commit=False)
            bomversion.creation_time = timezone.now()
            bomversion.material = material
            bomversion.save()

1 个答案:

答案 0 :(得分:0)

当您在表单上调用is_valid()时,它正在调用模型的干净方法。由于您仅在致电is_valid()后分配材料,因此在调用self.material时,self.material与任何Material对象无关。

您可以在调用is_valid()之前提出异常,而不是在clean方法上检查,因为您在保存表单时已经有了Material实例。从干净中删除支票,然后添加:

if model.objects.filter(material=material, is_default=True).count()  > 1:
    raise ValidationError('Material {} has a default value already'.format(material)) 

在保存实例之前调用is_clean()或某处之前。