Django 模型中验证器的问题

Problems with validators in django models

我想创建一个编辑页面,客户可以在其中编辑个人资料页面。我的验证器有问题,我不知道如何解决。

model.py

class UserProfile(models.Model):
CAT_G = (
        ('W', 'W'),
        ('M', 'M'),
        ('do not want to mention', 'do not want to mention'),
    )
    age = models.IntegerField(default=1, validators=[ MaxValueValidator(100), MinValueValidator(1)])
    height = models.DecimalField(max_digits=3, validators=[MinValueValidator(Decimal('0.0'))], decimal_places=2)
    gender = models.CharField(max_length=27, blank=False, null= False, choices=CAT_G)

view.py

def edit_view(request):
    context={}
    if request.method == "POST":
        form = ProfileUpForm(request.POST, instance=request.user.userprofile)
        if form.is_valid():
            form.save()
            return redirect('/profPage')
    else:
        form = ProfileUpForm(
            initial={
                "age":request.user.userprofile.age,
                "height":request.user.userprofile.height,
                "gender":request.user.userprofile.gender,
            }
        )

        context['profE_form']= form
        return render(request, 'editPage.html', context)

forms.py

class ProfileUpForm(forms.ModelForm):
    class Meta:
        model= UserProfile
        fields =('age', 'height', 'gender', )

    def clean_age(self):
        if self.is_valid():
            age=self.cleaned_data['age']
            return age
    
    def clean_height(self):
        if self.is_valid():
            height=self.cleaned_data['height']
            return height
   
    def clean_gender(self):
        if self.is_valid():
            gender=self.cleaned_data['gender']
            return gender

    

editPage.html

{% for fieldProfile in profE_form %}
            <p>
                {{fieldProfile.label_tag}}
                {{fieldProfile}}
            </p>
            {% endfor %}

问题是在 html 页面中,用户可以选择负数,即使我将验证器放入我的模型中也是如此。

您需要渲染字段的错误,所以:

{{ profE_form.non_field_errors }}
{% for fieldProfile in profE_form %}
<p>
    {{ fieldProfile.errors }}
    {{ fieldProfile.label_tag }}
    {{ fieldProfile }}
</p>
{% endfor %}

您还应该渲染 profE_form.non_field_errors。有关详细信息,请参阅 Rendering fields manually section of the documentation.

你不应该实现 .clean_…() 方法,绝对 你调用 is_valid() 的地方,因为 Django 调用这些 .clean_…() 来检查是否表格有效。

您可以通过指定小部件来指定 min and/or max:

from django.forms.widgets import NumberInput

class ProfileUpForm(forms.ModelForm):
    class Meta:
        model= UserProfile
        fields = ('age', 'height', 'gender', )
        widgets = {
            'age': NumberInput(attrs=dict(min=1, max=100)),
            'height': NumberInput(attrs=dict(min=0))
        }

您可以通过以下方式将实例传递给表单来简化视图:

from django.contrib.auth.decorators import login_required

@login_required
def edit_view(request):
    if request.method == 'POST':
        form = ProfileUpForm(request.POST, request.FILES, instance=request.user.userprofile)
        if form.is_valid():
            form.save()
            return redirect('/profPage')
    else:
        form = ProfileUpForm(instance=request.user.userprofile)

    context = {'profE_form': form}
    return render(request, 'editPage.html', context)

Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].