【问题标题】:Validations errors are not raising in clean function, Why?验证错误不会在 clean 函数中引发,为什么?
【发布时间】:2021-01-05 11:53:57
【问题描述】:

好吧,我正在使用带有 UpdateView 的 Userprofile 表单,即使我的条件为真,错误也不会出现。这种不良行为的可能性有多大。

forms.py.

class UserProfileForm(forms.ModelForm):
    
    class Meta:
        model = UserProfile
        fields = ("avatar","username","first_name","last_name","age","gender")
        # fields = ("avatar",)
        Gender = (
            ('one','Male'),
            ('two','Female'),
            )
            
        widgets ={
            'age' : forms.TextInput(attrs={'class':'form-control'}),
            'gender' : forms.Select(choices=Gender,attrs={'class': 'form-control'}),
        }
     # TRIED THIS AS WELL    
    # def clean_age(self):
    #     age = self.cleaned_data["age"]
    #     print(age,'hm here')
    #     if age < 18:
    #         print(age,'hm here')
    #         raise forms.ValidationError("You're age should be 18 plus")
    #     return age

    def clean(self):
        cleaned_data = super().clean()

        age = cleaned_data.get('age')
        print('haye',age)
        if age < 18:
            print(age,'hm here')
            # raise forms.ValidationError("You're age should be 18 plus")
            age = "You're age should be 18 plus"
            self.add_error('age',age)
            raise forms.ValidationError("You're age should be 18 plus")

views.py 这里我更新了用户模型字段,然后是 userprofile 字段,然后分别保存它们。

class UserProfileUpdateView(UpdateView):
    refirect_field_name ='accounts:profile'
    template_name = 'accounts/profiles/profile_update.html'
    form_class = UserProfileForm
    model = UserProfile

    def get_object(self, *args, **kwargs):
        return self.request.user.userprofile
    
    def get_context_data(self, *args, **kwargs):
        context = super(UserProfileUpdateView, self).get_context_data(*args, **kwargs)
        update_form = UserProfileForm(instance = self.request.user.userprofile)
        context['form']=update_form
        return context
    
    def form_valid(self, form):
            username = form.cleaned_data['username']
            print('username :',username)
            first_name = form.cleaned_data['first_name']
            print('first name :',first_name)
            last_name = form.cleaned_data['last_name']
            print('last name :',last_name)
            age = form.cleaned_data['age']
            print('age :',age)
            gender = form.cleaned_data['gender']
            print('gender :',gender)
            # usermodel save
            user = User.objects.get(username=self.request.user)
            print('GOT reqested User',user)
            user.username = username
            print('changed username :',user.username)
            user.age = age
            print('changed age :',user.age)
            user.gender = gender
            print('changed gender:',user.gender)
            user.first_name = first_name
            print('changed first name :',user.first_name)
            user.last_name = last_name
            print('changed last name :',user.last_name)
            user.save()
            # userprofile save
            profile = UserProfile.objects.get(user=self.request.user)
            print('GOT reqested User',profile)
            profile.username = username
            print('changed username :',profile.username)
            profile.age = age
            print('changed age :',profile.age)
            profile.gender = gender
            print('changed gender:',profile.gender)
            profile.first_name = first_name
            print('changed first name :',profile.first_name)
            profile.last_name = last_name
            print('changed last name :',profile.last_name)
            profile.save()
            form.save()
            return super().form_valid(form) 

models.py

class UserProfile(models.Model):

    user = models.OneToOneField(auth.models.User,related_name='userprofile', on_delete=models.CASCADE)
    avatar = models.ImageField(("displays"), upload_to='displays', height_field=None, width_field=None, max_length=None,default ='user.jpg')
    create_date = models.DateTimeField(default = timezone.now)
    Gender = (
    ('one','Male'),
    ('two','Female'),
    )
    first_name = models.CharField(("first_name"), max_length=50,null=True)
    last_name = models.CharField(("last_name"), max_length=50,null=True)
    username = models.CharField(("username"), max_length=50,null=True)
    age = models.IntegerField(("age"),null=True)
    gender = models.CharField(("gender"), max_length=50,choices=Gender,null=True)


    def __str__(self):
        return f'{self.user.username} UserProfile'
    
    def clean_fields(self, exclude=None):

        if self.age < 18:
            raise ValidationError(
                {"age": "You're age should be 18+"}
            )
        return super().clean_fields(exclude=exclude)

    def save(self,*args, **kwargs):
        if not self.username:
            self.username  = self.user.username
        if not self.age:
            self.age = self.user.age
        if not self.gender:
            self.gender  = self.user.gender
        if not self.first_name:
            self.first_name  = self.user.first_name
        if not self.last_name:
            self.last_name  = self.user.last_name
        super(UserProfile,self).save(*args, **kwargs)

请告诉我如何解决此问题并在无效细节上引发错误。 如果需要更多信息,请在评论部分告诉我,我会用这些信息更新我的问题。

【问题讨论】:

  • 您如何使用这些表格?添加你对应的views.py
  • 似乎您正在注册用户并将配置文件与其关联。由于这似乎是一个通用验证,您最好将此验证添加到您的 models.py 中的类 UserProfile
  • @JPG 我已经添加了views.py
  • @Agawane 如何清理模型中的表单数据,然后对其设置条件?

标签: django django-models django-rest-framework django-views django-forms


【解决方案1】:

通过使用这两种方法,无需重写表单的 clean 方法,并且每当您创建实例时都会验证对象。

方法一: 覆盖models.py中类UserProfile的clean_fields方法

def clean_fields(self, exclude=None):

    if self.age < 18:
        raise ValidationError(
            {"age": "You're age should be 18+"}
        )

    return super().clean_fields(exclude=exclude)

方法二: 在定义年龄字段时添加最小值验证

age = models.PositiveIntegerField(
    help_text="Age of the user.",
    validators=[
        MinValueValidator(
            18, "You're age should be 18+"
        )
    ]
)

您的意见:

def form_valid(self, form):
    # userprofile save
    profile = form.save(commit=False)
    # usermodel save
    user = self.request.user
    user.username = profile.username
    user.age = profile.age
    user.gender = profile.gender
    user.first_name = profile.first_name
    user.last_name = profile.last_name
    user.save()
    return super().form_valid(form)

【讨论】:

  • 没关系,我没有向您展示我的models.py,您是说我在models.py 中添加第一个方法对吗?我在理解你在回答中所说的内容时遇到了问题,你能告诉我我必须在我的代码中删除什么,我必须添加什么以及我必须在哪里添加。
  • 我已经添加了 models.py 并添加了您告诉我添加的第一个方法 models.py ,检查并告诉我我是否出错了,因为它不起作用。
  • 我之前没有在视图中注意到您的 form_valid。尝试方法 2。要使其与方法 1 一起使用,您需要在 profile.save() 之前调用 profile.full_clean()
  • 我从哪里导入MinValueValidato
  • 从 django.core.validators 导入 MinValueValidator
猜你喜欢
  • 2022-01-07
  • 2018-04-15
  • 2013-12-15
  • 2017-04-26
  • 2020-08-02
  • 1970-01-01
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多