0

I have a model in django that is as below:

class Student(Model):
    nationality = CharField(max_length=200)

I have a form as below:

class StudentForm(ModelForm):

    class Meta:
        model = Student
        fields = ('nationality', )

my template is as below:

<form method="GET" novalidate id="my_form">
      {{ student_form.as_p }}
</form>
<button type="submit" form="my_form" name="my_form">Submit</button>

I have a view as below:

def home(request):
    if request.POST:
        return HttpResponse('This should never happen')
    else:
        if request.GET.get('nationality'):
            student_form = StudentForm(request.GET)
            if student_form.is_valid():
                return HttpResponse('get from form submission')
        else:
            student_form = StudentForm()
            print('get from client request')
            return render(request, my_template, {'student_form': student_form}) 

The problem with this method is that if sb submits the form without filling the nationality field, the result would be 'get from client request' that is wrong because the validation error should happen because the request is from submitting a form not direct client get request. What I can do is that I add a hidden field to my form as below:

<form method="GET" novalidate id="my_form">
      {{ student_form.as_p }}
      <input type="hidden" id="hidden" name="hidden" value="hidden">
</form>
<button type="submit" form="my_form" name="my_form">Submit</button>

and change my view as below:

def home(request):
    if request.POST:
        return HttpResponse('This should never happen')
    else:
        if request.GET.get('hidden'):
            student_form = StudentForm(request.GET)
            if student_form.is_valid():
                return HttpResponse('get from form submission')
        else:
            student_form = StudentForm()
            print('get from client request')
            return render(request, my_template, {'student_form': student_form})

However, there should be another method to do this. There should be something in HTTP to tell us the request is fresh get request from client or it is from form submission. I am looking for this.

Amin Ba
  • 1,603
  • 1
  • 13
  • 38
  • If you want to submit form with data, method should be "post" and data submitted in form should be checked if request.method is "POST" – sandeep Sep 25 '19 at 05:34
  • Because I want to transfer the form data to the next page in which there is a bigger form that should partly be prefilled with the data of the home page form and there are different scenarios as well in the next page (fresh get directly from the client, the submission of the form of the page, and also submission of the form of the paginated pages of the second page), I need to use GET method. There is no problem with sending non-sensitive data with GET. part of the reason is explained in here: https://stackoverflow.com/questions/57941731/how-to-use-parse-qs-in-redirecting-from-view-to-another – Amin Ba Sep 25 '19 at 05:47
  • "if request.GET.get('nationality')" if this is true, then, form.is_valid will be true because I think nationallity is only field in form. Check the value of print(request.GET.get('nationality')) – sandeep Sep 25 '19 at 05:53
  • check what "print(request.GET.get('nationality'))" is printing. – sandeep Sep 25 '19 at 05:55
  • You did not notice the main issue. Because null and blank is false in the model, the model form validation requires that the submitted form be filled with a nationality(with sth). That is what I want!!! However, if sb submits the button without filling the nationality field, this will happen: ``` else: student_form = StudentForm() print('get from client request') return render(request, my_template, {'student_form': student_form}) ``` This is not what I want. – Amin Ba Sep 25 '19 at 06:00
  • That is why I solved it by adding a hidden field that is always prefilled. My problem is solved by doing this. However, I am looking for sth already available in the HTTP to eliminate the need for adding to it by including a hidden input. – Amin Ba Sep 25 '19 at 06:00
  • The solution to the pagination problem I mentioned above for which I have to use a get method (not related to this issue, provided here just as a reference): https://stackoverflow.com/questions/56799278/how-to-prevent-django-form-being-reset-after-clicking-page-buttons/57968098#57968098 – Amin Ba Sep 25 '19 at 06:05

1 Answers1

0

request.GET is a dictionary. request.GET.get('nationality') is falsy if the dictionary doesn't have the key 'nationality' but also if its value is the empty string (?nationality=). So you should just check the presence of the key, that way you know the form was submitted:

if 'nationality' in request.GET:
    # initialise form with `request.GET`
else:
    # initial unbound form
dirkgroten
  • 20,112
  • 2
  • 29
  • 42