I'm confused about how to pull in related information from two different tables.
If I go to localhost:8000/user/username, it should display the users profile and user reviews below. because the username is being passed through the URL into the views function. Is that correct?
Also, is it required that I use foreign key to accomplish this? I've read the docs and I'm still not completely sure how a foreign key would help me accomplish my goal here.
Models
from django.db import models
class User(models.Model):
name = models.CharField(max_length=20)
reviewer = models.CharField(max_length=20)
password = models.TextField()
zipcode = models.Charfield(max_length=100)
email = models.EmailField()
def __str__(self): # __unicode__ on Python 2
return self.name
class UserReview(models.Model):
name = models.ForeignKey(User)
author = models.CharField(max_length=50)
pub_date = models.DateField()
stars = models.IntegerField(max_length=5)
comment = models.CharField(max_length=100)
def __str__(self): # __unicode__ on Python 2
return self.name
Views
from django.shortcuts import render
def index(request):
profile_info = User.objects.filter(name=username)
context = {‘profile_info’: profile_info}
latest_reviews = UserReview.objects.filter(name=username).order_by('-pub_date')[:5]
context = {‘profile_info’: profile_info, 'latest_reviews': latest_reviews}
return render(request, 'randomtemplate.html', context)
URLS
urlpatterns = patterns('',
url(r'^user/(?P<username>\w+)/', 'index'),
)
There's a couple things you need to do. The first is that you need to pass the parameter into the view function, and then you'll need to display the ratings in the template.
#view
def index(request, username):
profile_info = User.objects.filter(name=username)
latest_reviews = UserReview.objects.filter(name=username).order_by('-pub_date')[:5]
context = {‘profile_info’: profile_info, 'latest_reviews': latest_reviews}
return render(request, 'randomtemplate.html', context)
# randomtemplate.html
{{ username }}
{{ latest_reviews }}
Related
I'm trying to test redirect from a form using POST. I'm following the mdn web doc tutorial for Django and thought I would see if I could do some of my own test which are not in the tutorial. I'm try to test the book creation form in the tutorial to see if it redirects to book details page which it should do automatically because it's a class based generic view. It works correctly when I test locally but I cannot get the testcase to pass. Thanks for the help in advance.
This is the error:
> =====================================================================
FAIL: test_redirects_to_book_details_on_success (catalog.tests.test_views.BookCreateView)
> ----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\makor\mypythonscripts\django_projects\locallibrary\catalog\tests\test_views.py", line 399, in test_redirects_to_book_details_on_success
self.assertRedirects(response, reverse('book-detail', kwargs={'pk': 1}))
File "C:\Users\makor\mypythonscripts\django_projects\venv\lib\site-packages\django\test\testcases.py", line 512, in assertRedirects
self.assertEqual(
AssertionError: 200 != 302 : Response didn't redirect as expected: Response code was 200 (expected 302)
----------------------------------------------------------------------
Ran 1 test in 0.341s
FAILED (failures=1)
Destroying test database for alias 'default'...
models.py
from django.db import models
from django.urls import reverse # Used to generate URLs by reversing the URL pattern.
from django.contrib.auth.models import User
from datetime import date
import uuid # Required for unique book instances
class Genre(models.Model):
"""Model representing book genre."""
name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)')
def __str__(self):
"""String representation of Model object."""
return self.name
class Language(models.Model):
"""Model representing a langauge."""
LANGUAGES = (
('English', 'English'),
('French', 'French'),
('German', 'German'),
('Spanish', 'Spanish'),
)
language = models.CharField(max_length=20, choices=LANGUAGES, blank=False, default='English', help_text='Availble languages')
def __str__(self):
"""String representation of Model object."""
return self.language
class Book(models.Model):
"""Model representing a book (but not a specific copy of a book)."""
title = models.CharField(max_length=200)
# Foreign Key used because book can only have one author, but author can have multiply books.
author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
summary = models.TextField(max_length=1000, help_text='Enter a brief description of the book.')
isbn = models.CharField('ISBN', max_length=13, unique=True,
help_text='13 character ISBN number')
# ManyToManyField used because genre can contain many books. Books can cover many genres.
# Genre class has already been defined, so we can specify the object above.
genre = models.ManyToManyField('Genre', help_text='Select a genre for this book.')
language = models.ManyToManyField('Language', help_text='Select the langauge.')
def __str__(self):
"""String for representing the Model object."""
return self.title
def get_absolute_url(self):
"""Returns the URL to access a detail record for this book."""
return reverse('book-detail', args=[str(self.id)])
def display_genre(self):
"""Create a string for the Genre. This is required to display genre in Admin."""
return ', '.join(genre.name for genre in self.genre.all()[:3])
display_genre.short_description = 'Genre'
class BookInstance(models.Model):
"""Model representing a specific copy of a book (i.e. that can be borrowed from the library)."""
id = models.UUIDField(primary_key=True, default=uuid.uuid4,
help_text='Unique ID for this particular book across the whole library.')
book = models.ForeignKey('Book', on_delete=models.RESTRICT, null=True)
imprint = models.CharField(max_length=200, blank=True)
due_back = models.DateField(null=True, blank=True)
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
LOAN_STATUS = (
('m', 'Maintenance'),
('o', 'On loan'),
('a', 'Available'),
('r', 'Reserved'),
)
status = models.CharField(
max_length=1,
choices=LOAN_STATUS,
blank=True,
default='m',
help_text='Book availability',
)
class Meta:
ordering = ['due_back']
permissions = (('can_mark_returned', 'set book as returned'),)
def __str__(self):
"""String representing the Model object."""
return f'{self.id} ({self.book.title})'
#property
def is_overdue(self):
"""Determines if the book is overdue based on due date and current date."""
return bool(self.due_back and date.today() > self.due_back)
class Author(models.Model):
"""Model representing an author."""
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField(null=True, blank=True)
date_of_death = models.DateField('died', null=True, blank=True)
class Meta:
ordering = ['last_name', 'first_name']
def get_absolute_url(self):
"""Returns the URL to access a particular author instance."""
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
"""String representing the Model object."""
return f'{self.last_name}, {self.first_name}'
views.py
import datetime
from django.views import generic
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse, reverse_lazy
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib.auth.decorators import login_required, permission_required
from . models import Book, Author, BookInstance, Genre, Language
from . forms import RenewBookForm
def index(request):
"""View function for home page of site."""
# Generate counts of some main objects.
num_books = Book.objects.all().count()
num_instances = BookInstance.objects.all().count()
# Available books (status = 'a')
num_instances_available = BookInstance.objects.filter(status__exact='a').count()
# The 'all()' is implied by default.
num_authors = Author.objects.count()
# Number of visits to this view, as counted in the session variable.
num_visits = request.session.get('num_visits', 0)
request.session['num_visits'] = num_visits + 1
# Generate counts for genre.
num_genre = Genre.objects.all().count()
# Filter books containing a particular word.
title = 'game of thrones'
num_title = Book.objects.filter(title__contains=title.lower()).count()
context = {
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
'num_genre': num_genre,
'num_title': num_title,
'num_visits': num_visits,
}
# Render the HTML template index.html with the data in the context variable.
return render(request, 'index.html', context=context)
class BookListView(generic.ListView):
model = Book
paginate_by = 10
class BookDetailView(generic.DetailView):
model = Book
class AuthorListView(generic.ListView):
model = Author
paginate_by = 10
class AuthorDetailView(generic.DetailView):
model = Author
class LoanedBooksByUserListView(LoginRequiredMixin, generic.ListView):
"""Generic class-based view listing books on loan to current user."""
model = BookInstance
template_name = 'catalog/bookinstance_list_borrowed_user.html'
paginate_by = 10
def get_queryset(self):
return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')
class BorrowedListView(PermissionRequiredMixin, generic.ListView):
"""Generic class-based view listing all books, requires correct permissions."""
permission_required = 'catalog.can_mark_returned'
model = BookInstance
template_name = 'catalog/borrowed_list.html'
paginate_by = 10
def get_queryset(self):
return BookInstance.objects.filter(status__exact='o').order_by('due_back')
#login_required
#permission_required('catalog.can_mark_returned', raise_exception=True)
def renew_book_librarian(request, pk):
book_instance = get_object_or_404(BookInstance, pk=pk)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = RenewBookForm(request.POST)
# Check if the form is valid
if form.is_valid():
# Process the data in form.cleaned_data as required (here we just write it to the model due_back field)
book_instance.due_back = form.cleaned_data['renewal_date']
book_instance.save()
# Redirect to a new URL:
return HttpResponseRedirect(reverse('all-borrowed'))
else:
context = {
'form': form,
'book_instance': book_instance,
}
return render(request, 'catalog/book_renew_librarian.html', context)
# If this is a GET (or any other method) create the default form.
else:
proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})
context = {
'form': form,
'book_instance': book_instance,
}
return render(request, 'catalog/book_renew_librarian.html', context)
class AuthorCreate(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
permission_required = 'catalog.can_mark_returned'
model = Author
fields = ['first_name', 'last_name', 'date_of_birth', 'date_of_death']
initial = {'date_of_death': '11/06/2022'}
class AuthorUpdate(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
permission_required = 'catalog.can_mark_returned'
model = Author
fields = '__all__' # Not recommended (potential security issue if more fields are added.)
class AuthorDelete(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
permission_required = 'catalog.can_mark_returned'
model = Author
success_url = reverse_lazy('authors')
class BookCreate(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
permission_required = 'catalog.can_mark_returned'
model = Book
fields = ['title', 'author', 'summary', 'isbn', 'genre', 'language']
class BookUpdate(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
permission_required = 'catalog.can_mark_returned'
model = Book
fields = '__all__'
class BookDelete(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
permission_required = 'catalog.can_mark_returned'
model = Book
success_url = reverse_lazy('books')
test.py
class BookCreateView(TestCase):
def setUp(self):
# Create a user
test_user1 = User.objects.create_user(username='testuser1', password='1X<ISRUkw+tuK')
test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&3iD')
test_user1.save()
test_user2.save()
# Give test_user2 permission to create Book.
permission = Permission.objects.get(name='set book as returned')
test_user2.user_permissions.add(permission)
test_user2.save()
test_author = Author.objects.create(first_name='John', last_name='Smith')
test_genre = Genre.objects.create(name='Fantasy')
test_language = Language.objects.create(language='English')
test_author.save()
test_genre.save()
test_language.save()
self.author = Author.objects.get(id=1)
self.genre = Genre.objects.get(id=1)
self.language = Language.objects.get(id=1)
def test_redirect_if_not_logged_in(self):
response = self.client.get(reverse('book-create'))
# Manually check redirect (Can't use assertRedirect, because the redirect URL is unpredictable)
self.assertEqual(response.status_code, 302)
self.assertTrue(response.url.startswith('/accounts/login/'))
def test_forbidden_if_logged_in_but_not_correct_permission(self):
login = self.client.login(username='testuser1', password='1X<ISRUkw+tuK')
response = self.client.get(reverse('book-create'))
self.assertEqual(response.status_code, 403)
def test_logged_in_with_permission_to_create_book(self):
login = self.client.login(username='testuser2', password='2HJ1vRV0Z&3iD')
response = self.client.get(reverse('book-create'))
# Check that it lets us login - this is our book and we have the right permissions.
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
login = self.client.login(username='testuser2', password='2HJ1vRV0Z&3iD')
response = self.client.get(reverse('book-create'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'catalog/book_form.html')
def test_redirects_to_book_details_on_success(self):
login = self.client.login(username='testuser2', password='2HJ1vRV0Z&3iD')
response = self.client.post(reverse('book-create'), {'title': 'Test',
'author': self.author,
'summary': 'It\'s all good',
'isbn': '1234567',
'genre': self.genre,
'language': self.language,
})
self.assertRedirects(response, reverse('book-detail', kwargs={'pk': 1}))
form template
{% extends 'base_generic.html' %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit" />
</form>
{% endblock %}
Screenshot of form
I have been at this for about two days but I think my beginners luck has ran out. I can usually figure it out by myself after a while but not anymore as this is my first post. I think the data i am entering into the client.post is not working and giving the correct response object. Sorry if my lingo is not correct as I am new to all this.
I am new to Django and I need to know how to have DetailView and UpdateView on the same Page.
I have two Models:
class Company(models.Model):
CustomerNo = models.AutoField(primary_key=True)
Company = models.CharField(max_length=200)
Str = models.CharField(max_length=200)
Zip = models.IntegerField()
City = models.CharField(max_length=200)
Name = models.CharField(max_length=200)
Phone = models.IntegerField()
Mobile = models.IntegerField()
Email = models.EmailField(max_length=200)
Web = models.CharField(max_length=200)
Info = models.CharField(max_length=200)
def __str__(self):
return self.Company
class Contact(models.Model):
Contact_Company = models.ForeignKey(Company, on_delete=models.CASCADE)
Contact_Name = models.CharField(max_length=200)
Contact_Phone = models.IntegerField()
Contact_Mobile = models.IntegerField()
Contact_Fax = models.IntegerField()
Contact_E_Mail = models.EmailField()
Contact_Web = models.CharField(max_length=200)
def __str__(self):
return self.Contact_Name
I want to build a page where I can see the company data from the first model and an update form for contacts realeted to the first model.
I enter the page with pk, from the previous page, its a DetailView for the first Model and with additionally context to list the Contact data with a for loop in Template.
I can use UpdateView to get data in the form and save it. but I don't know
how do display the realeted Company on the same page. Is there a way to use DetailView and UpdateView together?
I can use this UpdateView to change the Contact data, but I don't know how to include extra context from the first model to display the address on same page.
The success URL is wrong too.
I need to pass the pk from the first model so I can go back to the right list on previous page.
class ContactUpdate(UpdateView):
model = Contact
form_class = ContactCreateForm
template_name = 'customer/contact_update.html'
def get_success_url(self):
return reverse('customer_list', kwargs={'pk': self.object.pk})
def get_context_data(self, **kwargs):
context = super(ContactUpdate, self).get_context_data(**kwargs)
return context
Maybe FormMixin is a solution, I used it to Display the Data from
first Model and form for second Model on same Page. But I am really stuck
to realize this with UpdateForm.
I hope you understand my problem, sorry for my english.
Thank you for your help.
Forms.py
from django.forms import ModelForm
from .models import Company
from .models import Contact
from django.forms import HiddenInput
from django import forms
class CompanyCreateForm(ModelForm):
class Meta:
model = Company
fields = '__all__'
class ContactCreateForm(ModelForm):
class Meta:
model = Contact
widgets = {'Contact_Company': forms.HiddenInput()}
fields = [
'Contact_Company',
'Contact_Name',
'Contact_Phone',
'Contact_Mobile',
'Contact_Fax',
'Contact_E_Mail',
'Contact_Web',
You need to add form in the detail view,
class PostDetailView(DetailView):
model = Post #your model name
template_name = 'detail.html' #your template
# here you will add your form
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
context['contactupdateform'] = ContactCreateForm()
return context
# Add POST method
def post(self, request, slug):
post = get_object_or_404(Post, slug=slug)
form = contactupdateform(request.POST)
if form.is_valid():
# from here you need to change your post request according to your requirement, this is just a demo
obj = form.save(commit=False)
obj.post = post
obj.author = self.request.user #to add the user
obj.save()
return redirect('detail', post.slug) #add your url
Make sure you are adding the POST request correctly, according to your model and url. This is an outline you can refer.
To add the form in the HTML, you need to do this,
{% for form in contactupdateform %}
<-- Add Your CSRF token and form here --!>
{% endfor %}
You can import this (LoginRequiredMixin) and insert in the updateview as an argument as the contact is a user
then try putting this in the models.py file :
def get_absolute_url(self):
return reverse('customer_list', kwargs={'pk': self.pk})
and remove (get_success_url) from views.py
You might need these too in the updateview Class "ContactUpdate"
login_url = '/login/'
redirect_field_name = <-- template path(html) of the page you want to reverse to...
HOPE THIS HELPS...
I have a model 'Playlist' with an attribute 'private' that can be True or False (and therefore private or public). I want to use the #login_required decorator only if 'private = False', but can't figure out how to achieve this result. Here is my models.py file:
class Playlist(models.Model):
"""Allow a user to create a customized list of songs."""
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='playlists/%Y/%m/%d', blank=True, null=True)
songs = models.ManyToManyField('Song')
description = models.TextField(blank=True, null=True, max_length=1000)
date_added = models.DateTimeField(auto_now_add=True)
private = models.BooleanField()
def __str__(self):
"""String for representing the model object."""
return self.name
def get_absolute_url(self):
"""Returns the url to access a detail record for this song."""
return reverse('playlist-detail', args=[str(self.id)])
And my views.py file:
def playlist(request, playlist_id):
"""Show a single playlist and associated data."""
playlist = Playlist.objects.get(id=playlist_id)
songs = playlist.songs.all()
for song in songs:
if song.url:
song.video_id = song.url.replace("https://www.youtube.com/watch?v=", "")
context = {'playlist': playlist, "playlist_songs": songs}
return render(request, 'great_songs_app/playlist.html', context)
I stumbled across a similar thread but there was no answer to the problem:Conditionally apply login_required decorator in Django
I imagine code looking something like what the OP posted, with the view function being preceded by:
if playlist.private == True:
#login_required
...
But obviously that won't work. Any ideas?
Rather than trying to apply #login_required, you could simply let the view undecorated and do something like the following, checking whether the user is authenticated:
from django.shortcuts import redirect
from django.conf import settings
def playlist(request, playlist_id):
"""Show a single playlist and associated data if user is authenticated."""
playlist = Playlist.objects.get(id=playlist_id)
if not playlist.private or (playlist.private and request.user.is_authenticated):
songs = playlist.songs.all()
for song in songs:
if song.url:
song.video_id = song.url.replace("https://www.youtube.com/watch?v=", "")
context = {'playlist': playlist, "playlist_songs": songs}
return render(request, 'great_songs_app/playlist.html', context)
else:
redirect(settings.LOGIN_URL)
I am writing the create method for a post, which belongs to a group and a user. I keep getting this error, although this is how it's done in the documentation and every other source i've looked at. here are the relevant files:
models.py
from django.db import models
from django.contrib.auth.models import User, Group
class Post(models.Model):
title = models.CharField(max_length=255, unique=True)
body = models.TextField()
likes_total = models.IntegerField(default=0)
pub_date = models.DateTimeField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
def __str__(self):
return self.name
def summary(self):
# return the 1st 100 chars
return self.body[:100]
def pub_date_pretty(self):
# strftime is how to break down time
return self.pub_date.strftime('%b %e %Y')
posts.urls.py
from . import views
from django.urls import path
app_name = 'posts'
urlpatterns = [
path('create/<int:group_id>/', views.create, name='create'),
]
posts.views.py
def create(request, group_id):
group = get_object_or_404(Group, pk= group_id)
if request.method == 'POST':
if request.POST['body']:
post = Post()
post.title = request.POST['title']
post.body = request.POST['body']
post.pub_date = timezone.datetime.now()
post.author = request.user
post.group = group
post.save()
return redirect('/groups/' + str(group_id))
else:
return render(request, 'groups/detail.html', {'group':group})
else:
return render(request, 'groups/detail.html', {'group':group})
the error is thrown when I am saving the group to the post (post.group = group), although this the method that ive learned. Hope someone can figure this out. thanks!!
You seem to have mixed up two different Group models. In your model you have:
from django.contrib.auth.models import User, Group
and in your view you have:
from groups.models import Group
These are completely different classes, which is why you get an error telling you that you can't assign groups.models.Group to what should be a auth.models.Group.
I'm not sure which you intend it to be, but you need to use the same class in both places.
I create a modelForm with instance to existing model (Book). I am not able to update the Books record. Adding a new record is fine but when I attempt to update, it appears to be unable to find the publisher (which is a foreign key). Error is "No Publisher matches the given query."
models.py
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Meta:
ordering = ["name"]
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, verbose_name='e-mail')
objects = models.Manager()
sel_objects=AuthorManager()
def __unicode__(self):
return self.first_name+' '+ self.last_name
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField(blank=True, null=True)
num_pages = models.IntegerField(blank=True, null=True)
class BookForm(ModelForm):
class Meta:
model = Book
views.py
def authorcontactupd(request,id):
if request.method == 'POST':
a=Author.objects.get(pk=int(id))
form = AuthorForm(request.POST, instance=a)
if form.is_valid():
form.save()
return HttpResponseRedirect('/contact/created')
else:
a=Author.objects.get(pk=int(id))
form = AuthorForm(instance=a)
return render_to_response('author_form.html', {'form': form})
error msg
Page not found (404)
Request Method: POST
Request URL: http://127.0.0.1:8000/books/bookupd/
No Publisher matches the given query.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
urls.py
from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
from mysite10.books.views import about_pages, books_by_publisher, authorcontact,bookcontact, booklisting, authorcontactupd
from django.views.generic import list_detail
from mysite10.books.models import Publisher, Book
from django.contrib import admin
admin.autodiscover()
def get_books():
return Book.objects.all()
publisher_info = {
'queryset': Publisher.objects.all(),
'template_name':'books/publisher_publisher_list_page.html',
'template_object_name': 'publisher',
'extra_context': {'book_list': Book.objects.all},
}
book_info = {
'queryset': Book.objects.order_by('-publication_date'),
'template_name':'books/publisher_publisher_list_page.html',
'template_object_name': 'book',
'extra_context': {'publisher_list': Publisher.objects.all},
}
oreilly_books = {
'queryset': Book.objects.filter(publisher__name="O'Reilly"),
'template_name':'books/publisher_publisher_list_page.html',
'template_object_name': 'book',
'extra_context': {'publisher_list': Publisher.objects.all},
}
urlpatterns = patterns('',
(r'^admin/(.*)', admin.site.root),
(r'^polls/', include('mysite10.polls.urls')),
(r'^search-form/$', 'mysite10.views.search_form'),
(r'^search/$', 'mysite10.views.search'),
(r'^contact/$', 'mysite10.contact.views.contact'),
(r'^contact/thanks2/(\d+)$', 'mysite10.contact.views.thanks2'),
(r'^contact/thanks/$', 'mysite10.contact.views.thanks'),
(r'^publishers/$', list_detail.object_list, publisher_info),
(r'^books/$', list_detail.object_list, book_info),
(r'^books/oreilly/$', list_detail.object_list, oreilly_books),
(r'^books/(\w+)/$', books_by_publisher),
(r'^author/$', authorcontact),
(r'^authorupd/(\d+)/$', authorcontactupd),
(r'^contact/created/$', 'mysite10.books.views.created'),
(r'^bookform/$', bookcontact),
(r'^contact/bookscreated/$', 'mysite10.books.views.books_created'),
(r'^booklist/$', 'mysite10.books.views.booklisting'),
(r'^books/bookupd/(\d+)$', 'mysite10.books.views.book_upd'),
)
-------------------------------------------------
I finally got it working with below codes.
error in urls.py because of missing forward slash before $.
Amended to (r'^books/bookupd/(\d+)/$'
views.py
def book_upd(request,id):
if request.method == 'POST':
a=Book.objects.get(pk=int(id))
form = BookForm(request.POST, instance=a)
if form.is_valid():
form.save()
return HttpResponseRedirect('/contact/bookscreated')
else:
a=Book.objects.get(pk=int(id))
form = BookForm(instance=a)
return render_to_response('book_form.html', {'form': form})
urls.py
(r'^books/bookupd/(\d+)/$', 'mysite10.books.views.book_upd'),
There's some missing information like what you have in your urls.py. Can you post it as well? Did you check in the database that the record was actually not updated? (the error might be a result of processing the redirect)
Your edit is not sufficient:
- did you check the databse to see if the record is updated?
- Please paste the entire urls.py as for example it is interesting to see what /contact/created is mapped to in case it did succeed, or whether you have some publisher.get() methods in it
In addition the traceback can also provide lots of useful information as to the source of the problem.
did you check if the object is updated in the database even though you get the error?
Can you try removing the "oreilly_books" section (or at least the queryset part) and try doing the same without it?