Джанго поднимает формы. ValidationError не работает

Я пытаюсь добавить валидатор в форму модели django, чтобы, если выбрано конкретное значение, нужно было ввести другое поле в форме, если оно не введено, оно должно дать ошибку проверки

в приведенной ниже форме, если пользователь выбирает «Действия по поддержке проекта» в раскрывающемся списке «имя_деятельности», тогда поле идентификатора проекта должно быть обязательным.

Форма Джанго

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

Вид :


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)

person Abdul Baseer    schedule 12.04.2019    source источник


Ответы (2)


Поднятие ошибки работает нормально. Но вы всегда перенаправляете, даже если форма недействительна, поэтому ошибка никогда не будет отображаться.

Вы должны перенаправлять только тогда, когда is_valid имеет значение True, в противном случае вы должны повторно отобразить форму. Это означает передачу недопустимой формы обратно в контекст, поэтому вам следует создавать новую только тогда, когда метод не POST. Так:

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)
person Daniel Roseman    schedule 12.04.2019
comment
Теперь форма не сохраняется, что ожидается, но она не отображает ошибку проверки в форме. - person Abdul Baseer; 12.04.2019
comment
Как вы показываете эти ошибки? Покажите шаблон. - person Daniel Roseman; 12.04.2019
comment
Выяснилось, что у моего валидатора также были некоторые проблемы, так как project_id - это CharField, его нельзя проверить с помощью Null, поскольку никакие входные данные не изменили валидатор, как показано ниже, и он работал 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 - person Abdul Baseer; 12.04.2019

Изменено MY View, как упоминалось @Daniel Roseman, и изменен валидатор формы.

Вид

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)

Валидатор формы

    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
person Abdul Baseer    schedule 12.04.2019