Search code examples
pythonhtmldjangoapi-design

Form POST to database via Django doesn't save data


following a Django tutorial, i coded the following html file that takes a form filled by a user and adds it to the database as an object (the form is a bunch of attributes of a class)


{% block content %}

<form>
<form method="POST"> {% csrf_token %} 
    {{ form.as_p }}
<input type='submit' value = 'save' />
</form>
{% endblock %}

instead of saving the form to the database, it adds a weird string to the url (pasted below). this happened to the guy in the tutorial, but it was fixed after he added the <form method="POST"> {% csrf_token %} what is this "error", and how can i deal with it? also, what can i do if it happens in the future?

there's no real error, the server goes on fine, so there's no traceback/error message to show. i made sure the form.as_p is a real variable, and that there's no typos in the variables or tags relative to the tutorial. only problem i can think of is the change in versions - the tutorial is in Django 2.0.7 and i am on 3.2.5, but the csrf_token is still valid according to what i saw in the docs.

added to the url below. i know the end if just the values of the form (asd,asd,1), but what is the rest and what do i do to fix it? ?csrfmiddlewaretoken=KWR2kXFqa3k1ETQsuyhKmHN6cJvZfj72KHkw1v4aGYTdThW9S7zWylCFJpNjhVDB&title=asd&description=asd&price=1

thank you!

edit:

forms.py:

from django import forms
from .models import product

class ProductForm(forms.ModelForm):
    class Meta:
    model = product
        fields = ['title','description','price']

views.py:

def product_create_view(request):
    form = ProductForm(request.POST or None)
    if form.is_valid():
        form.save()
    context = {
        'form': form
    }

    return render (request, 'product/product_create.html', context)

also: removed the {% csrf_token %} from the code, and it still didnt work. it just put the form input in the url and didnt save it.


Solution

  • Your form has a wrong extra tag

    {% block content %}
    
    <form> <!-- Remove this  -->
    <form method="POST"> {% csrf_token %} 
        {{ form.as_p }}
    <input type='submit' value = 'save' />
    </form>
    {% endblock %}
    

    This makes your form use the default method (which is GET, not POST), hence the fact that your data is added in the URL instead. The CSRF is nothing more than an extra field in your form, that's why it's in the url as well