Django raise forms.ValidationError not working

不问归期 提交于 2020-01-17 01:36:48

问题


I am trying to add a validator to django model form such that if specific value is selected then other field in the form should be entered if not entered it should give a validation error

in the below form if the user selects "Project Support Activities" from the activity_name drop down then the project id field should be mandatory

Django Form

class ActivityTrackerModelForm(forms.ModelForm):
    date = forms.DateField(label='', widget=forms.DateInput(attrs={
                           "placeholder": "Select Date", 'id': 'datepicker', 'class': 'form-control w-100', 'autocomplete': 'off'}))
    activity_name = forms.ModelChoiceField(queryset=activity.objects.all().order_by(
        'activity_name'), label='', empty_label="Select Activity", widget=forms.Select(attrs={'class': 'form-control w-100'}))
    system_name = forms.ModelChoiceField(queryset=system.objects.all().order_by('system_name'), label='', empty_label="Select System", widget=forms.Select(attrs={
'class': 'form-control w-100'}))
    client_name = forms.ModelChoiceField(queryset=client.objects.all().order_by(
        'client_name'), label='',  empty_label="Select Client", widget=forms.Select(attrs={
'class': 'form-control w-100'}))
    hour_choice = [('', 'Choose Hours'), (0, 0), (1, 1), (2, 2),(3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8)]
    hours = forms.ChoiceField(label='', choices=hour_choice, widget=forms.Select(
        attrs={'class': 'form-control w-100'}))
    min_choice = [('', 'Choose Mins'), (0, 0), (15, 15), (30, 30), (45, 45)]
    mins = forms.ChoiceField(label='', choices=min_choice, widget=forms.Select(attrs={'class': 'form-control w-100'}))
    no_of_records = forms.IntegerField(label='', required=False, widget=forms.NumberInput(
        attrs={"placeholder": "Enter no. of Records", 'class': 'form-control w-100', 'autocomplete': 'off'}))
    project_id = forms.CharField(label='', required=False, widget=forms.TextInput(
        attrs={"placeholder": "Project ID", 'class': 'form-control w-100'}))
    user_comments = forms.CharField(
        label='',
        required=False,
        widget=forms.Textarea(
            attrs={
                "placeholder": "Enter Your Comments Here...",
                'rows': 6,
                'class': 'form-control w-100',
                'autocomplete': 'off'
            }
        )
    )

    class Meta:
        model = activity_tracker
        fields = ['date', 'activity_name', 'system_name', 'client_name',
                  'hours', 'mins', 'no_of_records', 'project_id', 'user_comments']


    def clean(self):
        cleaned_data = super(ActivityTrackerModelForm, self).clean()
        activity = cleaned_data.get('activity_name')
        project_1 = cleaned_data.get('project_id')
        if re.search("^Project.*Activities$", str(activity)) or project_1 is None:
            print('pass') # prints to console this is working
            raise forms.ValidationError('Please Add in Project ID')#raise form error this is not working

View :


def MyTask(request):
    if request.method == 'POST':
        form = ActivityTrackerModelForm(request.POST or None)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.user_name = request.user
            obj.approver = tascaty_user.objects.get(
                username=request.user).approver
            if request.user.is_team_lead:
                obj.status = activity_status.objects.get(pk=3)
            obj.save()
        return redirect('mytask')

    queryset1_PA = activity_tracker.objects.filter(
        user_name=request.user).filter(status__in=[1, 2, 4]).order_by('-id')
    queryset1_AP = activity_tracker.objects.filter(
        user_name=request.user).filter(status=3).order_by('-date')
    paginator_RA = Paginator(queryset1_AP, 10)
    paginator_PA = Paginator(queryset1_PA, 10)
    page = request.GET.get('page')

    context = {
        'title': 'TasCaty|My Task',
        'activity_form': ActivityTrackerModelForm(),
        'post_page_RA': paginator_RA.get_page(page),
        'post_page_PA': paginator_PA.get_page(page),
    }
    return render(request, "tascaty/mytask.html", context)

回答1:


Raising the error is working fine. But you always redirect away, even if the form is not valid, so the error will never be displayed.

You should only redirect when is_valid is True, otherwise you should redisplay the form. That means passing the invalid form back to the context - so you should only create a new one when method is not POST. So:

if request.method == 'POST':
    form = ActivityTrackerModelForm(request.POST or None)
    if form.is_valid():
        ...
        obj.save()
        return redirect('mytask')   # indented here
else:
    ActivityTrackerModelForm()      # added this block, note it's aligned with the first if

...

context = {
    ...
    'activity_form': form,         # pass the existing form here
    ...
}
return render(request, "tascaty/mytask.html", context)



回答2:


Changed MY View as mentioned by @Daniel Roseman and changed form validator

View

if request.method == 'POST':
    form = ActivityTrackerModelForm(request.POST or None)
    if form.is_valid():
        ...
        obj.save()
        return redirect('mytask')   # indented here
else:
    ActivityTrackerModelForm()      # added this block, note it's aligned with the first if

...

context = {
    ...
    'activity_form': form,         # pass the existing form here
    ...
}
return render(request, "tascaty/mytask.html", context)

Form Validator

    def clean(self):
        cleaned_data = super(ActivityTrackerModelForm, self).clean()
        activity = cleaned_data.get('activity_name')
        project_1 = cleaned_data.get('project_id')
        if re.search("^Project.*Activities$", str(activity)) and project_1 == "":
            self.add_error('project_id', "Please Add Project ID")
        return cleaned_data


来源:https://stackoverflow.com/questions/55650306/django-raise-forms-validationerror-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!