2

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)),
)

2 Answers 2

2

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)),
)
Sign up to request clarification or add additional context in comments.

6 Comments

i have added the urlpatterns just as you told, but as i click the submit the data, the url is not able to find addbook view. is there any other way of adding url into `form' action?
My urls.py is in the project directory. I used this but still the urlpatterns issue is there. I tried concatenating a new urlpatterns with the original one. It still doesn't works.
@mozart Ok I updated my answer sorry I forgot to put views in the url that's why it's not working
I have already tried that way. Should I add a new template addbook?
much better so that you will not be able to put url in the form
|
2

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.

3 Comments

it now says: 'url' requires a non-empty first argument. What does that mean?
It's an error with the {% url book_view %} tag. Read up on the function - docs.djangoproject.com/en/dev/topics/http/urls/…
You could replace it with the actual url to make it work but you shouldn't be using hardcoded url's - do read up on the reverse function to get an understanding of how it works (you'll need to make changes to your url.conf).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.