Sumit Gera
Sumit Gera

Reputation: 1241

How to configure HTML form to work with django models?

I am trying to configure HTML formto work with Django Models rather than using built-in Forms in the framework. I have made the form using Html below and have pasted the code for Model, View and Urls.py. The problem is when I click the submit button, it doesn't perform any action. I am able to view the form but it doesn't serves the purpose. I know the question is very lame, but how would configure the HTML to work with the django model so that the data can be saved to the database?

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
</head>
<body style="font-family:Courier New">
    <h1>Add / Edit Book</h1>
    <hr/>
    <form id="formHook" action="/istreetapp/addbook" method="post">
        <p style="font-family:Courier New">Name <input type="text" placeholder="Name of the book"></input></p>
        <p style="font-family:Courier New">Author <input type="text" placeholder="Author of the book"></input></p>
        <p style="font-family:Courier New"> Status
            <select>
                <option value="Read">Read</option>
                <option value="Unread">Unread</option>
            </select>
        </p>
    <input type="submit" id="booksubmit" value="Submit"></input>
</form>
</body>
</html>

View

from django.shortcuts import HttpResponse
from istreetapp.models import bookInfo
from django.template import Context, loader
from django.shortcuts import render_to_response

def index(request):
    booklist = bookInfo.objects.all().order_by('Author')[:10]
    temp = loader.get_template('app/index.html')
    contxt = Context({
        'booklist' : booklist,
    })
return HttpResponse(temp.render(contxt))

Model

from django.db import models

class bookInfo(models.Model):
    Name = models.CharField(max_length=100)
    Author = models.CharField(max_length=100)
    Status = models.IntegerField(default=0) # status is 1 if book has been read

def addbook(request, Name, Author):
    book = bookInfo(Name = Name, Author=Author)
    book.save
    return render(request, 'templates/index.html', {'Name': Name, 'Author': Author})

Urls.py

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('app.views',
    url(r'^$', 'index'),
    url(r'^addbook/$', 'addbook'),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)

Upvotes: 2

Views: 519

Answers (2)

catherine
catherine

Reputation: 22808

You forgot to define name in each of your input

<form id="formHook" action="/addbook/" method="post">
    {% csrf_token %}
    <p style="font-family:Courier New">
        Name <input type="text" name="name" placeholder="Name of the book"></input>
    </p>

    <p style="font-family:Courier New">
        Author <input type="text" name="author" placeholder="Author of the book"></input>
    </p>

    <p style="font-family:Courier New"> 
        Status
        <select name="status">
            <option value="Read">Read</option>
            <option value="Unread">Unread</option>
        </select>
    </p>
    <input type="submit" id="booksubmit" value="Submit"></input>
</form>

Your addbook must be in the views.py not in your models.py. You don't have to define templates/index.html in your render, it is understood in your settings

def addbook(request):
    if request.method == 'POST':
        name = request.POST['name']
        author = request.POST['author']
        bookInfo.objects.create(Name = name, Author=author)
        return render(request, 'index.html', {'Name': name, 'Author': author})

main urlconf

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', 'project_name.views.index'),
    url(r'^addbook/$', 'project_name.views.addbook'),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)

Upvotes: 2

Aidan Ewen
Aidan Ewen

Reputation: 13328

You need to add name attributes to your html form then process the form submission in the view. Something like -

from django.http import HttpResponseRedirect
from django.shortcuts import render

def book_view(request):
    if request.method == 'POST':
        name = request.POST['name']
        author = request.POST['author']
        book = BookInfo(name=name, author=author)
        if book.is_valid():
            book.save()
            return HttpResponseRedirect('your_redirect_url')
    else:
        return render(request, 'your_form_page.html')

Have a look at the docs on the request.POST dictionary.

However you really would be better off doing this with a django ModelForm -

class BookForm(ModelForm):
    class Meta:
        model = BookInfo # I know you've called it bookInfo, but it should be BookInfo

then in your view -

from django.http import HttpResponseRedirect
from django.shortcuts import render

def book_view(request, pk=None):
    if pk:
        book = get_object_or_404(BookInfo, pk=pk)
    else:
        book = BookInfo()
    if request.method == 'POST':
        form = BookForm(request.POST, instance=book)
        if form.is_valid():
            book = form.save()
            return HttpResponseRedirect('thanks_page')
    else:
        form = BookForm(instance=book)
    return render(request, 'your_form_page.html', {'form': form)

And your_form_page.html can be as simple as -

<form action="{% url book_view %}" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit" />
</form>

Have a look at the docs on working with forms.

Upvotes: 2

Related Questions