Django form not saving – cannot identify problem with code

Question:

Trying to save the below form, but it’s not saving.

The traceback doesn’t identify any problem, and print(form.errors) doesnt not return any issue.

I have the exact same code working for another page. So I am not sure what I am missing here. There has to be a typo, I cannot find it.

You will notice that I have an autocomplete function in my template. I initially thought autocomplete was not returning data in all the fields, so also tried to input data manually but not luck either.

Also tried with and without is_ajax but same result.

models.py:

class Venue(models.Model):
    name = models.CharField(verbose_name="Name",max_length=100, null=True, blank=True)
    address = models.CharField(verbose_name="Address",max_length=100, null=True, blank=True)
    town = models.CharField(verbose_name="Town",max_length=100, null=True, blank=True)
    county = models.CharField(verbose_name="County",max_length=100, null=True, blank=True)
    post_code = models.CharField(verbose_name="Post Code",max_length=8, null=True, blank=True)
    country_1 = models.CharField(verbose_name="Country1",max_length=100, null=True, blank=True)
    country_2 = models.CharField(verbose_name="Country2",max_length=100, null=True, blank=True)
    longitude = models.CharField(verbose_name="Longitude",max_length=50, null=True, blank=True)
    latitude = models.CharField(verbose_name="Latitude",max_length=50, null=True, blank=True)
    phone = models.CharField(max_length=120)
    web = models.URLField('Website Address')
    email_address = models.EmailField('Venue Email Address')
    
    def __str__(self):
        return str(self.name) if self.name else ''

forms.py:

class VenueForm(ModelForm):
    name = forms.CharField(max_length=100, required=True, widget = forms.TextInput(attrs={'id':"name"}))
    address = forms.CharField(max_length=100, widget = forms.TextInput(attrs={'id':"address"}))
    town = forms.CharField(max_length=100, required=True, widget = forms.TextInput(attrs={'id':"town"}))
    county = forms.CharField(max_length=100, required=True, widget = forms.TextInput(attrs={'id':"county"}))
    post_code = forms.CharField(max_length=8, required=True, widget = forms.TextInput(attrs={'id':"post_code"}))
    country_1 = forms.CharField(max_length=40, required=True, widget = forms.TextInput(attrs={'id':"country_1"}))
    country_2 = forms.CharField(max_length=40, required=True, widget = forms.TextInput(attrs={'id':"country_2"}))
    longitude = forms.CharField(max_length=50, required=False, widget = forms.TextInput(attrs={'id':"longitude"}))
    latitude = forms.CharField(max_length=50, required=False, widget = forms.TextInput(attrs={'id':"latitude"}))
    phone = forms.CharField(max_length=120,required=False)
    web = forms.URLField(max_length=120,required=False)
    email_address = forms.CharField(max_length=120, required=False)

    class Meta:
        model = Venue
        fields = ['name', 'address', 'town', 'county', 'post_code','country_1','country_2','longitude','latitude','web', 'phone', 'email_address']

views.py:

def google_api_test(request):
    submitted = False
    form = VenueForm()
    if is_ajax(request) and request.method =="POST":
        form = VenueForm(data = request.POST)
        if form.is_valid():
            form.save()
            messages.success(request,("Success!"))
            return redirect('home')
        else :
            print(form.errors)
    context = {
    'form' : form,
    'submitted' : submitted,
    'google_api_key' : settings.GOOGLE_API_KEY,
    'base_country' : settings.BASE_COUNTRY,
    }
    return render(request,"main/google_api_test.html", context)

html file:

<div class = "form-group">

         <input id="autocomplete" style ="width: 500px "placeholder="Enter your address">

         <form id="venueform" method="POST" action="">
            {% csrf_token %}
            {{ form|as_crispy_errors }}
            <td class="label">Name (Name)</td>
            {{form.name| as_crispy_field}}
         </br>
            <td class="label">Street Number + Street Name (Address)</td>
            {{form.address| as_crispy_field}}
        </br>
            <td class="label">Town (town)</td>
            {{form.town | as_crispy_field}}
        </br>
            <td class="label">Country(country_1)</td>
            {{form.country_1| as_crispy_field}}
        </br>
            <td class="label">Post Code (post_code)</td>
            {{form.post_code| as_crispy_field}}
        </br>
            <td class="label">Country(country_2)</td>
            {{form.country_2| as_crispy_field}}
        </br>
            <td class="label">Country(longitude)</td>
            {{form.longitude| as_crispy_field}}
        </br>
            <td class="label">Country(latitude)</td>
            {{form.latitude| as_crispy_field}}
        </br>
            <td class="label">phone(phone)</td>
            {{form.phone| as_crispy_field}}
        </br>
            <td class="label">web(web)</td>
            {{form.web| as_crispy_field}}
        </br>
            <td class="label">email_address(email_address)</td>
            {{form.email_address| as_crispy_field}}
        </br>

        <button type="submit" value="Submit" id="profile-btn">Validate</button>
        </form>
    </div>
Asked By: PhilM

||

Answers:

county is missing in your template. It’s weird that your print(form.errors) did not show up in your terminal – it should have

Answered By: royshoo
def google_api_test(request):
    submitted = False
    
    if is_ajax(request) and request.method == 'POST':
        print(request.POST) # Check--Are you getting form data
        form = VenueForm(data = request.POST)
        if form.is_valid():
            form.save()
            messages.success(request,("Success!"))
            return redirect('home')
        else :
            print(form.errors)

    else:
       form = VenueForm() #Changes in here.

    context = {
    'form' : form,
    'submitted' : submitted,
    'google_api_key' : settings.GOOGLE_API_KEY,
    'base_country' : settings.BASE_COUNTRY,
    }
    return render(request,"main/google_api_test.html", context)
Answered By: Iqbal Hussain

Firstly, I’d recommend you to check whether the form even goes to the POST method of google_api_view or not since you mentioned form.errors prints nothing.

Remove the empty action="" from the html form, since Django always takes current page route or url, so it is unnecessary.

Also suggest not to use is_ajax(request) only for one time to check(I think it’s depreciated).

So, try this view:

def google_api_test(request):
    submitted = False
    
    form="" # for the error - local variable 'form' referenced before assignment if occurs.
    if request.method == 'POST':
        print("POST method") # check it prints it or not.
        form = VenueForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request,"Success!")
            return redirect('home')
        else:
            print(form.errors)

    else: # GET request
       form = VenueForm()

    context = {
    'form' : form,
    'submitted' : submitted,
    'google_api_key' : settings.GOOGLE_API_KEY,
    'base_country' : settings.BASE_COUNTRY,
    }
    return render(request,"main/google_api_test.html", context)

Also share Ajax and jQuery code.

Answered By: Sunderam Dubey