简体   繁体   English

基于同一模型中其他字段的Django字段验证器

[英]django field validator based on other field in same model

I have this model 我有这个模特

class Env(models.Model):    
    functional_count = models.PositiveIntegerField()    
    current_count = models.PositiveIntegerField()

Now i want functional_count to always be less than current_count . 现在我希望functional_count始终小于current_count
So during create, 因此在创建过程中

def form_valid(self, form):    
    form.instance.current_count = 0

This is because i want current_count during initialization.Then my python code never allows current_count to go above functional_count . 这是因为我希望current_count initialization.Then在我的Python代码永远不会允许current_count上面去functional_count

The problem comes in Update. 问题来自更新。

class EnvUpdate(UpdateView):  
    model = Capacity.models.Envapps  
    fields = ['functional_count']  
    template_name_suffix = '_update_form'

So do i include a validator? 那我包括验证器吗? If yes, where and how? 如果是,在哪里和如何?
Or other option is to verify in get_success_url() . 或其他选择是在get_success_url()进行验证。
Any other solution? 还有其他解决方案吗?

Assuming your updates come through a form (as suggested by the use of form_valid() , perhaps you can use the form clean() method, as described in the documentation . This allows you to perform checks for fields that depend on each other. The documentation also has an example which should get you further. 假设您的更新是通过表单form_valid() (如使用form_valid()所建议的form_valid() ,也许您可​​以按照文档中的描述使用clean()方法,这使您可以检查彼此依赖的字段。文档中还有一个示例,可以使您更进一步。

Update 更新

From your comments, I understand that you tried to use clean() inside EnvUpdate , which inherits from the class-based UpdateView view. 根据您的评论,我了解到您尝试在EnvUpdate使用clean() ,该方法继承自基于类的UpdateView视图。 All the mixins provided through UpdateView do apparently not provide a clean() method, so you can't override it. 通过UpdateView提供的所有mixin显然都没有提供clean()方法,因此您不能覆盖它。

I am actually referring to the clean() in a form class (as follows from the link). 我实际上是在表单类中引用clean() (如下链接所示)。 So, it looks like you'd need to create your own ModelForm class, something like: 因此,看起来您需要创建自己的ModelForm类,例如:

class EnvappsForm(forms.ModelForm):
    class Meta:
        model = Capacity.models.Envapps
        fields = ['functional_count']

    def clean(self):
       cleaned_data = super(ContactForm, self).clean()
       if cleaned_data['functional_count'] >= form.instance.current_count:
           raise ValidationError('too large')
       return cleaned_data

and then in your view: 然后您认为:

class EnvUpdate(UpdateView):
    model = Capacity.models.Envapps  
    template_name_suffix = '_update_form'
    form_class = EnvappsForm

Note: this is completely untested! 注意:这是完全未经测试的! I don't know if the comparison in the clean() works (ie, if form.instance.current_count can be found), and wheter EnvUpdate will override the form_class (it shouldn't, but I've never tried). 我不知道clean()的比较是否有效(即,是否可以找到form.instance.current_count),而EnvUpdate会覆盖form_class(它不应该,但是我从未尝试过)。 It just might be even possible that you can remove the meta subclass, and provide the model and fields from EnvUpdate , as you do yourself above. 也许会是甚至有可能,你可以删除meta的子类,并提供modelfieldsEnvUpdate ,你做你之上。 That's just something you can easily try out. 您可以轻松尝试一下。

If functional_count should always be less than current_count you should check it in the clean() method on the model and not some random ModelForm . 如果functional_count始终小于current_count ,则应在模型的clean()方法中进行检查,而不应使用某些随机的ModelForm The model clean() will be called during normal ModelForm validation. 在常规ModelForm验证期间将调用模型clean()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM