Problems with rendering page on Django framework - python

I have categories of the news and news and i don't know how to render the page with the list of news that belong to the same category. Hope You will help me with that.
this is my model.py file:
from django.db import models
class Category(models.Model):
class Meta:
verbose_name_plural = u'Categories'
category = models.CharField(max_length=255)
slug = models.CharField(max_length=255)
def __unicode__(self):
return self.category
class News(models.Model):
class Meta:
verbose_name_plural = u'News'
title = models.CharField(max_length=255)
category = models.ForeignKey(u'Category', related_name=u'Category', blank=True, null=True)
pub_date = models.DateTimeField('date published')
slug = models.CharField(max_length=255)
short_content=models.TextField(max_length=2000, blank=True)
content = models.TextField(max_length=10000)
image = models.FileField(u'Images', upload_to='media/img/news', blank=True)
def __unicode__(self):
return self.title
views.py:
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from news.models import News
class NewsListView(ListView):
template_name ='news/list.html'
context_object_name = 'news_list'
def get_queryset(self):
return News.objects.order_by('-pub_date') [:5]
class NewsDetailView(DetailView):
model=News
template_name = 'news/detail.html'
def CategoryNews(request, categoryslug):
category = Category.objects.get(slug=categoryslug)
news = News.objects.filter(category=category)
return render (request, 'news/category_news.html', {'category' : category})
urls.py:
django.conf.urls import patterns, url
from news.views import NewsListView, NewsDetailView
from news import views
urlpatterns = patterns('',
url(r'^$', NewsListView.as_view(), name='list'),
url(r'^(?P<slug>[-_\w]+)/$', NewsDetailView.as_view()),
url(r'^kids-garden/$', views.CategoryNews),
)
Thank You!

On CategoryNews view add news to render context. This will make news items available in templates.
def CategoryNews(request, categoryslug):
category = Category.objects.get(slug=categoryslug)
news = News.objects.filter(category=category)
return render (request, 'news/category_news.html', {'category' : category, 'newsitems': news})
Add named group to category url to make it dynamic.
Rewrite
url(r'^kids-garden/$', views.CategoryNews, name='category'),
to
url(r'^category/(?P<categoryslug>\w+)/$', views.CategoryNews, name='category'),
In category_news.html
{%for news in newsitems%}
{{ news.title }}
{{ news.content }}
# rest values...........
{% endfor %}

I think this should do the job:
views.py
....
from news.models import News, Category
def CategoryNews(request, categoryslug):
category_news = News.objects.filter(category__slug='categoryslug')
return render (request, 'news/category_news.html', {'category_news' : category_news})

Related

models.py order of the models gives NameError: name 'Category/Post' is not defined

I'm new to Django so this is probably a dumb question but,
when I put the class Category model above the class Post model I get an
NameError: name 'Post' is not defined error.
but when I try to put class Category model underneath the Post model (as in the code here) I get
categories = models.ManyToManyField(Category)
NameError: name 'Category' is not defined error.
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE) #if is deleted than delete their posts
location = models.CharField(max_length=100, default="")
tags = TaggableManager()
likes = models.ManyToManyField(User, related_name='blog_posts')
categories = models.ManyToManyField(Category)
def total_likes(self):
return self.likes.count()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
class Category(models.Model):
post = models.ForeignKey(Post, related_name="categories")
name = models.CharField(max_length=20)
def __str__(self):
return self.name
admin.py
from django.contrib import admin
from .models import Post, Comment, Category #, Konum
# Register your models here.
admin.site.register(Post)
admin.site.register(Comment)
admin.site.register(Category)
#admin.site.register(Konum)
some of the code
<form method="GET" action=".">
<div class="form-group col-md-4">
<label for="category">Category</label>
<select id="category" class="form-control" name="category">
<option selected>Choose...</option>
{% for cat in categories %}
<option value="{{ cat }}">{{ cat }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
views.py
def home(request):
context = {
"posts": Post.objects.all()
}
return render(request, 'blog/home.html', context)
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------
def filter(request):
qs = Post.objects.all()
categories = Category.objects.all()
id_exact_query = request.GET.get('id_exact')
title_or_author_query = request.GET.get('title_or_author')
category = request.GET.get('category')
if is_valid_queryparam(category) and category != 'Choose...':
qs = qs.filter(categories__name=category)
context = {
'posts': qs,
'categories': Category.objects.all()
}
return render(request, 'blog/home.html', context)
class PostListView(ListView):
model = Post
template_name = 'blog/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 199
class UserPostListView(ListView):
model = Post
template_name = 'blog/user_posts.html'
context_object_name = 'posts'
paginate_by = 199
def get_queryset(self):
return Post.objects.filter(author = user).order_by('-date_posted')
urls.py
from django.urls import path, re_path
from .import views
from .views import PostListView, PostDetailView, PostCreateView, PostUpdateView, PostDeleteView, UserPostListView, TagIndexView, LikeView #, LocationPostListView
urlpatterns = [
path('', PostListView.as_view(), name="blog-home"), #has a empty strting bc its already processed blog part in main urls
path('user/<str:username>', UserPostListView.as_view(), name="user-posts"),
#--------------------------------------------------------------------------------------------------------------------------------------
#path('location/<str:loc>', LocationPostListView.as_view(), name="location-posts"),
#--------------------------------------------------------------------------------------------------------------------------------------
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),#pk means primary key like post 1 post 2 etc
path('post/new/', PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
path('about/', views.about, name="blog-about"),
#--------------------------------------------------------------------------------------------------------------------------------------
path('tag/<slug:slug>/', TagIndexView.as_view(), name='tagged'),
path('like/<int:pk>', LikeView, name='like_post'),
#--------------------------------------------------------------------------------------------------------------------------------------
]
You can use a string literal to specify the model name of a model that still needs to be defined, so you can use ManyToManyField('Category') or ForeignKey('Post', on_delete=models.CASCADE) for example to refer to models not yet defined:
from django.conf import settings
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
location = models.CharField(max_length=100, default="")
tags = TaggableManager()
likes = models.ManyToManyField(settings.AUTH_USER_MODELS, related_name='liked_posts')
categories = models.ManyToManyField('Category')
It however does not seem to make much sense that a Category has a ForeignKey to a post: that would mean that a Category links to exactly one Post record?
You can for example use a ListView with:
class PostListView(ListView):
model = Post
template_name = 'blog/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 199
def get_queryset(self):
qs = super().get_queryset()
if self.request.GET.get('category'):
return qs.filter(categories__name=self.request.GET['category'])
return qs
def get_context_data(self, *args, **kwargs):
context = super().get_queryset(*args, **kwargs)
context['categories'] = Category.objects.all()
return context
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Subcategories display in Django

Hope you can help me with this one.I am very new to Python/Django so my code might be quite bad.
I am creating a website/blog and on my navigation bar I have a list of the categories which contain dropdown menues with the subcategories. When I click on each subcategory I want it to display just the posts from that subcategory.
Here is part of my code for this:
"Models":
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
from django.urls import reverse
from ckeditor_uploader.fields import RichTextUploadingField
class Post(models.Model):
NO_CATEGORY = 'No Category'
GETTING_STARTED = 'Getting Started'
DIY = "DIY"
GARDENS = 'Gardens'
TERRARIUMS = 'Terrariums'
CATEGORIES = (
(NO_CATEGORY, 'No Category'),
(GETTING_STARTED, 'Getting Started'),
(DIY, 'DIY'),
(GARDENS, 'Gardens'),
(TERRARIUMS, 'Terrariums'),
)
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(unique=True, default='', blank=True)
image = models.ImageField(upload_to='images/')
content = RichTextUploadingField(null=True, blank=True)
summary = models.CharField(max_length=150, unique=True, null=True)
category = models.CharField(choices=CATEGORIES, max_length=15, default=NO_CATEGORY)
subcategory = models.ForeignKey('Subcategory', on_delete=models.SET_NULL, null=True)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('core:post_detail', args=[str(self.slug)])
class Meta:
ordering = ['-created_date']
class Subcategory(models.Model):
NO_CATEGORY = 'No Category'
TOOLS = 'Tools'
HOW_TO = 'How To'
SUPPLIES = 'Supplies'
FURNITURE = 'Furniture'
ACCESSORIES = 'Accessories'
DECOR = 'Decor'
MINIATURE = 'Miniature'
MICRO = 'Micro'
OPEN = 'Open'
ENCLOSED = 'Enclosed'
SUBCATEGORIES = [
(NO_CATEGORY, 'No Category'),
('Getting Started', ((TOOLS, 'Tools'), (HOW_TO, 'How To'), (SUPPLIES, 'Supplies'),)),
('DIY', ((FURNITURE, 'Furniture'), (ACCESSORIES, 'Accessories'), (DECOR, 'Decor'),)),
('Gardens', ((MINIATURE, 'Miniature'), (MICRO, 'Micro'),)),
('Terrariums', ((OPEN, 'Open'), (ENCLOSED, 'Enclosed'),)),
]
name = models.CharField(choices=SUBCATEGORIES, max_length=15, default=NO_CATEGORY)
slug = models.SlugField(max_length=150, unique=True, null=True)
class Meta:
verbose_name = "Subcategory"
verbose_name_plural = "Subcategories"
def get_posts(self):
return Post.objects.filter(subcategories_name=self.name)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('core:post_subcategory', kwargs={'slug': self.slug})
class Picture(models.Model):
title = models.CharField(max_length=100, unique=True)
image = models.ImageField(upload_to='images/gallery/')
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return f'{self.title}'
class Meta:
ordering = ['-created_date']
"Views":
from django.shortcuts import render
from .models import Post, Subcategory, Picture
from django.core.paginator import Paginator
from django.views import generic
def base(request):
return render(request, 'core/base.html')
def home(request):
posts = Post.objects.all()
paginator = Paginator(posts, 5)
page = request.GET.get('page')
posts = paginator.get_page(page)
return render(request, 'core/home.html', {'posts': posts})
class PostList(generic.ListView):
model = Post
queryset = Post.objects.all().order_by('-created_date')
template_name = 'home.html'
def post_detail(request, slug=None):
post = Post.objects.get(slug=slug)
return render(request, 'core/post_detail.html', {'post': post})
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def post_subcategory(request):
subcategories = Subcategory.objects.all()
paginator = Paginator(subcategories, 5)
page = request.GET.get('page')
subcategories = paginator.get_page(page)
return render(request, 'core/post_subcategory.html', {'subcategories': subcategories})
class SubcategoryDetailView(generic.DetailView):
model = Subcategory
context_object_name = 'subcategory'
template_name = 'core/post_subcategory.html'
def get_queryset(self):
return Post.objects.filter(subcategory_id=self.kwargs.get('slug'))
def base_gallery(request):
pictures = Picture.objects.all()
paginator = Paginator(pictures, 16)
page = request.GET.get('page')
pictures = paginator.get_page(page)
return render(request, 'core/base_gallery.html', {'pictures': pictures})
class PictureList(generic.ListView):
queryset = Picture.objects.all().order_by('-created_date')
template_name = 'base_gallery.html'
def contact(request):
return render(request, 'core/contact.html', {'contact': contact})
"config/urls"
from django.shortcuts import render
from .models import Post, Subcategory, Picture
from django.core.paginator import Paginator
from django.views import generic
def base(request):
return render(request, 'core/base.html')
def home(request):
posts = Post.objects.all()
paginator = Paginator(posts, 5)
page = request.GET.get('page')
posts = paginator.get_page(page)
return render(request, 'core/home.html', {'posts': posts})
class PostList(generic.ListView):
model = Post
queryset = Post.objects.all().order_by('-created_date')
template_name = 'home.html'
def post_detail(request, slug=None):
post = Post.objects.get(slug=slug)
return render(request, 'core/post_detail.html', {'post': post})
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def post_subcategory(request):
subcategories = Subcategory.objects.all()
paginator = Paginator(subcategories, 5)
page = request.GET.get('page')
subcategories = paginator.get_page(page)
return render(request, 'core/post_subcategory.html', {'subcategories': subcategories})
class SubcategoryDetailView(generic.DetailView):
model = Subcategory
context_object_name = 'subcategory'
template_name = 'core/post_subcategory.html'
def get_queryset(self):
return Post.objects.filter(subcategory_id=self.kwargs.get('slug'))
def base_gallery(request):
pictures = Picture.objects.all()
paginator = Paginator(pictures, 16)
page = request.GET.get('page')
pictures = paginator.get_page(page)
return render(request, 'core/base_gallery.html', {'pictures': pictures})
class PictureList(generic.ListView):
queryset = Picture.objects.all().order_by('-created_date')
template_name = 'base_gallery.html'
def contact(request):
return render(request, 'core/contact.html', {'contact': contact})
"app/urls":
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
import core.views
urlpatterns = [
path('admin/', admin.site.urls),
path('core/', include('core.urls')),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('', core.views.home, name='home'),
path('', core.views.base, name='base'),
path('post_subcategory', core.views.post_subcategory, name='post_subcategory'),
path('post_detail', core.views.post_detail, name='post_detail'),
path('base_gallery', core.views.base_gallery, name='base_gallery'),
path('contact', core.views.contact, name='contact')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
"post_category.html":
{% extends "core/base.html" %}
{% block content %}
{% load static %}
<div class="category-title">
<h1>HOW TO</h1>
</div>
{% for subcategory in subcategories %}
{% for post in subcategory.post_set.all %}
<h1>{{ post.title }}</h1>
<div class="category-content">
<figure class="gallery-picture">
<h1 class="picture-text"></h1>
<img src="{{ post.image.url }}" alt="gallery image">
</figure>
</div>
{% endfor %}
{% endfor %}
{% endblock %}
This is what I've tried so far and I can display all the subcategories on that template but I don't know how to filter them one by one, if that makes any sense.
First, I think the data structure and your model relationships are not properly placed.
I think you should have a category model and a sub_category model too.
class Category(models.Model):
title = models.Charfield(...)
class SubCategory(models.Model):
category = models.ForiegnKey(on_delete=models.CASCADE)
title = models.Charfield(...)
By doing this, you wouldn't need the dictionary and you won't also need the category field on Post model
so all have to query in your views.py is where post.sub_category.category == the requested category or where post.sub_cateogory == the requested sub_category.
Editing to show how to implement in views.py
class DIYCategoryList(generic.ListView):
template_name = 'blog/diy_category.html'
model = Post
context_object_name = 'diy_posts'
paginate_by = 16
def get_queryset(self):
return Post.objects.filter(sub_category.category.title='DIY')

template not displaying information - django

I can't figure out why my data won't display in my user.html template. From reviewing the code it looks like everything is linked correctly. The users.html page is showing up on the website minus the information about {{ user.order_set.all }}. I have highlighted the code I believe relates to the issue. Any guidance would be greatly appreciated, thanks!
user.html - html for displaying the data
{% extends "fuisce/base.html" %}
{% block content %}
**{{ user.order_set.all }}**
{% endblock content %}
views.py - order
from django.shortcuts import render, HttpResponseRedirect
from django.urls import reverse
# Create your views here.
from carts.models import Cart
from .models import Order
from users.models import Profile
from .utils import id_generator
**def orders(request):
context = {}
template = "orders/user.html"
return render(request, template, context)**
def checkout(request):
try:
the_id = request.session['cart_id']
cart = Cart.objects.get(id=the_id)
except:
the_id = None
return HttpResponseRedirect(reverse("cart"))
new_order, created = Order.objects.get_or_create(cart=cart)
if created:
new_order.order_id = id_generator()
new_order.save()
my_p = Profile.objects.get(user=request.user)
new_order.user = my_p
new_order.save()
if new_order.status == "Finished":
# cart.delete()
del request.session['cart_id']
del request.session['items_total']
return HttpResponseRedirect(reverse("cart"))
context = {}
template = "fuisce/about.html"
return render(request, template, context)
models.py - orders
from django.db import models
# Create your models here.
from carts.models import Cart
from users.models import Profile
STATUS_CHOICES =(
("Started", "Started"),
("Abandoned", "Abandoned"),
("Finished", "Finished"),
)
class Order(models.Model):
**user = models.ForeignKey('users.Profile', null=True, blank=True, on_delete=models.CASCADE)**
order_id = models.CharField(max_length=120, default='ABC', unique=True)
cart = models.ForeignKey('carts.Cart', on_delete=models.CASCADE)
status = models.CharField(max_length=120, choices=STATUS_CHOICES, default="Started")
sub_total = models.DecimalField(default=10.99, max_digits=1000, decimal_places=2)
tax_total = models.DecimalField(default=10.99, max_digits=1000, decimal_places=2)
final_total = models.DecimalField(default=10.99, max_digits=1000, decimal_places=2)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __string__(self):
return self.order_id
urls.py
from django.urls import path
from . import views
from carts import views as cart_views
from orders import views as order_views
urlpatterns = [
path('', views.home, name='fuisce-home'),
path('subscription/', views.subscription, name='fuisce-subscription'),
path('oneoff/', views.oneoff, name='fuisce-oneoff'),
path('about/', views.about, name='fuisce-about'),
path('contact/', views.contact, name='fuisce-contact'),
path('cart/', cart_views.view, name='cart'),
path('cart/<int:id>/', cart_views.remove_from_cart, name='remove_from_cart'),
path('cart/<slug>/', cart_views.add_to_cart, name='add_to_cart'),
path('checkout/', order_views.checkout, name='checkout'),
**path('orders/', order_views.orders, name='user_orders'),**
]
Based on the comments to the question, it seems you have a ForeignKey field to Profile and not to User.
Either change your ForeignKey from Profile to User like this:
class Order(models.Model):
user = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
null=True,
blank=True)
Or use a different lookup in your template:
{{ user.profile.order_set.all }}

how to query get posts filtered with same category in django functional based view

I am trying to list out all posts with same catgory on my home page in django. I want title to be category title and then below title it should render all the posts related to that catgory. I did this in class based view by finding help on stackoverflow but I want to know this in functional based view to understand this.
posts/models.py
from tinymce import HTMLField
from django.db import models
from django.contrib.auth import get_user_model
from slugger import AutoSlugField
from django.urls import reverse
# Create your models here.
User = get_user_model()
def upload_location(instance, filename):
return "%s/%s" %(instance.slug, filename)
class Author(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return self.user.username
class Category(models.Model):
title = models.CharField(max_length=20)
slug = AutoSlugField(populate_from='title')
def __str__(self):
return self.title
class Post(models.Model):
title = models.CharField(max_length = 100)
slug = AutoSlugField(populate_from='title')
overview = models.CharField(max_length= 200)
timestamp = models.DateTimeField(auto_now_add=True)
content = HTMLField()
comment_count = models.IntegerField(default=0)
view_count = models.IntegerField(default=0)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
thumbnail = models.ImageField(
upload_to=upload_location,
null=True,
blank=True)
category = models.ManyToManyField(Category)
featured = models.BooleanField()
previous_post = models.ForeignKey('self', related_name= 'previous', on_delete=models.SET_NULL, blank=True, null=True)
next_post = models.ForeignKey('self', related_name= 'next', on_delete=models.SET_NULL, blank=True, null=True)
def __str__(self):
return self.title
posts/views.py I tried to do this but this gives me error something like this
TypeError at /
index() missing 1 required positional argument: 'category_slug'
from django.shortcuts import render
from .models import Post, Author, Category
# Create your views here.
def index(request):
featured = Post.objects.filter(featured = True) #put this on carousel
latest_post = Post.objects.order_by('-timestamp')[:6]
category = Category.objects.filter(slug= category_slug)
post_by_category = Post.objects.filter(category=category)
context = {
'object_list': featured,
'latest_post': latest_post,
'post_by_category': post_by_category,
}
return render(request, 'index.html', context)
urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from posts.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('', index),
path('tinymce/', include('tinymce.urls'))
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
when you use a function based view like yours: def index(request, category_slug): you are declaring a query_param and you have to catch it in your url. Try this:
path('<str:category_slug>', index)
as your indexview
So this will be your url where you get the category slug to filter out the posts
path('<str:category_slug>', index)
Your request function must have the url parameter as an argument so that you can query the category from the db, in this case it is category_slug
def index(request, category_slug):
category = Category.objects.get(slug=category_slug)
post_by_category = Post.objects.filter(category=category)
Remember, filter() returns a list of instances, so use get() instead.

Passing data with CreateView in django

I am getting the error:
NOT NULL constraint failed: films_comment.film_id
On the comments page there is a form field called body for the comment itself, I also need it to store this comment against the user and the film.
Models:
from django.db import models
from django.urls import reverse
class Film(models.Model):
title = models.CharField(max_length=200)
director = models.CharField(max_length=200)
description = models.CharField(max_length=200)
pub_date = models.DateField('date published')
def get_absolute_url(self):
return reverse('films:detail', kwargs={'pk' : self.pk})
class Comment(models.Model):
# user = models.ForeignKey(User, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
film = models.ForeignKey(Film, on_delete=models.CASCADE)
body = models.CharField(max_length=200)
Views:
from django.views import generic
from .models import Film, Comment
from django.views.generic.edit import CreateView, UpdateView, DeleteView
class IndexView(generic.ListView):
# model = Film
template_name = 'films/index.html'
# context_object_name = 'object_list'
def get_queryset(self):
return Film.objects.all()
class DetailView(generic.DetailView):
model = Film
template_name = 'films/detail.html'
class CommentCreate(CreateView):
model = Comment
fields = ['body']
Urls:
app_name = 'films'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
# path('<int:film_id>/comment', views.add_comment, name='add_comment'),
path('<int:pk>', views.DetailView.as_view(), name='detail'),
path('<int:film_id>/comment/', views.CommentCreate.as_view(), name='add_comment'),
]
Link on details page for adding a comment:
Leave a comment
comment_form.py:
<form action="" method="post">
{% csrf_token %}
{% include 'films/form-template.html' %}
<button type="submit">Submit</button>
</form>
Form template:
{% for field in form %}
{{field.errors}}
<label>{{ field.label_tag }}</label>
{{ field }}
{% endfor %}
forms.py
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('body',)
You need to override view's form_valid method to update new comment instance with current user and film:
class CommentCreate(CreateView):
model = Comment
fields = ['body']
def form_valid(self, form):
film = Film.objects.get(pk=self.kwargs['film_id'])
form.instance.user = self.request.user
form.instance.film = film
return super(CommentCreate, self).form_valid(form)
To fix "No URL redirect to" you can add get_absolute_url() method to the Comment model:
def get_absolute_url(self):
return reverse('detail', kwargs={'pk': self.film.pk})

Categories

Resources