0

I'm new into programming (just started learning Django&Python). I'm having issues in validating a form used for a DB search.The form should validate if the first field is empty or if the second and third fields are empty. At this moment the behavior is kinda strange. If i remove the form validation everything works as expected in terms of search functionality. With it in place as bellow NO validation is done BUT weird things start to happen:

If i enter valid data for 1st field or (field 2 &field 3) -> valid data is returned (expected)

If i leave the fields empty and hit search all DB data is returned (not expected)

If i enter wrong data only for field 2 or field 3 all DB data is returned (not expected)

If i enter wrong data for field 1 or field 2 & field 3 nothing is returned (expected)

Totally appreciate any help?

#forms.py:

class SearchForm(forms.ModelForm):  
    cnp_nbr = forms.IntegerField(label='CNP', widget=forms.TextInput(attrs={'class': 'form-control' }), required=False)  
    first_name = forms.CharField(label='First Name', widget=forms.TextInput(attrs={'class': 'form-control'}),  required=False)  
    last_name = forms.CharField(label='Last Name', widget=forms.TextInput(attrs={'class': 'form-control'}),  required=False)


    def clean(self):  # most used!!!
        all_clean_data = super().clean()
        cnp_nbr = all_clean_data.get('cnp_nbr')
        first_name = all_clean_data.get('first_name')
        last_name = all_clean_data.get('last_name')


        if not cnp_nbr and not first_name and not last_name :
            raise forms.ValidationError(" enter f1 or f2&f3")

        if not first_name and last_name or first_name  and not last_name :
            raise forms.ValidationError("enter f2&f3 ")

        return all_clean_data

     class Meta():
        model = Clients                                
        fields = ('cnp_nbr','first_name','last_name')


#Views.py

class ClientsSearch(generic.FormView):
    form_class = forms.SearchForm
    model = models.Clients
    template_name = "administration/clients_search.html"

class SearchResults (generic.ListView):
    model = models.Clients
    template_name='administration/search_results.html'
    context_object_name = 'all_search_results'
    form = forms.SearchForm

    def get_queryset(self): 
        form = forms.SearchForm(self.request.GET)
        if form.is_valid():
                return self.model.objects.filter(
            Q(cnp_nbr__exact=form.cleaned_data['cnp_nbr']) |Q(first_name__exact=form.cleaned_data['first_name']) & Q(last_name__exact=form.cleaned_data['last_name'])
        )

        return models.Clients.objects.all()


#HTML:

 <form method="GET"  action="{% url 'administration:searchresults' %}"  >
    {% csrf_token %}
    {{ form.as_p }}
    <button id="submit" name = "submit" type="submit">Search</button>
  </form>
Doro
  • 1
  • 2

1 Answers1

0

If I understood your requirements correctly, your clean method should look like this:

def clean(self):  # most used!!!
    all_clean_data = super().clean()
    cnp_nbr = all_clean_data.get('cnp_nbr')
    first_name = all_clean_data.get('first_name')
    last_name = all_clean_data.get('last_name')

    if not cnp_nbr or not (first_name and last_name):
        raise forms.ValidationError("Enter f1 or f2&f3")

    return all_clean_data
  • What exactly is not working? And what do you want to happen if all fields are left empty? – Olzhas Arystanov Jan 23 '20 at 19:24
  • I'm expecting to receive the error in the form if all fields are left empty (or 2&3); more than that i receive all DB data when pressing Search button (if i remove the clean method at least nothing is returned) – Doro Jan 23 '20 at 19:38
  • From here https://stackoverflow.com/questions/53470065/stuck-with-django-form-validation. "The default a FormView will only process the form on POST; the GET is for initially displaying the empty form. So you need to use method="post" in your template form element."I have fixed the data returned"; (the strange return of data was due to another mistake) – Doro Jan 24 '20 at 17:14