ListView and DetailView in Django - python

I have 4 categories on my site. How can I write one class PageViews(ListView) for four same pages with different posts. And same question, how to write class DeteilViews(DetailView) for each posts? My models below.
class Category(models.Model):
category = models.CharField(max_length=50)
slug = models.CharField(max_length=60, unique=True)
class Topic(models.Model):
topic = models.CharField(max_length=50)
slug = models.CharField(max_length=60, unique=True)
category = models.ManyToManyField(Category)
class Page(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
datetime = models.DateTimeField()
title = models.CharField(max_length=60)
slug = models.CharField(max_length=250, unique=True)
short_text = models.CharField(max_length=255)
text = models.TextField()
image = models.ImageField(upload_to='media/news_img')
img_source = models.CharField(max_length=255)
page_source = models.CharField(max_length=60)
parsing_date = models.DateTimeField(auto_now=True)
objects = models.Manager()
def get_absolute_url(self):
return reverse('news:detail', args=[self.category.slug, self.topic.slug, self.slug])
class Comment(models.Model):
page = models.ForeignKey(Page, on_delete=models.CASCADE)
comment = models.TextField()
author = models.CharField(max_length=55)
datetime = models.DateTimeField()
I tried write, but failed...
For example:
class DetailView(DetailView):
template_name = 'post.html'
model = Page
def guery_set(self):
return self.request.GET.get('slug')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['posts'] = Page.objects.filter(slug=slug)
return context
And:
class PageView(ListView, SingleObjectMixin):
template_name = 'page_body.html'
paginate_by = 8
def get(self, request, *args, **kwargs):
self.object = self.get_object(
queryset=Category.objects.all())
return super().get(request, *args, **kwargs)
def get_queryset(self):
return Page.objects.filter(category=self.object)
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs)
pages = ????
context['posts'] = pages[:8]
return context

Related

Showing two model in same page Django

I have two models:
class Post(models.Model):
title= models.CharField(max_length=255)
author = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
postimage = models.ImageField(null= True, blank= True, upload_to="images/")
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title + " | "+ str(self.author)
def get_absolute_url(self):
return reverse('article_deatil', args=(str(self.id)))
class AboutMe(models.Model):
title1= models.CharField(max_length=255, default="About Me")
body = models.TextField()
skill1= models.CharField(max_length=255)
skill1body = models.TextField()
skill2= models.CharField(max_length=255)
skill2body = models.TextField()
skill3= models.CharField(max_length=255)
skill3body = models.TextField()
edu1=models.CharField(max_length=255)
edu1body = models.TextField()
edu2=models.CharField(max_length=255)
edu2body = models.TextField()
edu3=models.CharField(max_length=255)
edu3body = models.TextField()
def __str__(self):
return self.title1
I want to show both of them in my home.html
class HomeView(ListView):
model = Post
template_name = 'home.html'
queryset = Post.objects.order_by('-published_date')[:3]
url.py
urlpatterns = [
path('',HomeView.as_view(), name="home"),
path('',PostViewList.as_view(), name="postlist"),
]
I'm new to django and not sure how to show case two model in one template. I did put the post.body and other tags in my html but it not showing the About me part.
Assuming that you want one more queryset of AboutMe model like Post model.
You should simply use get_context_data() in the following way:
class HomeView(ListView):
model = Post
template_name = 'home.html'
queryset = Post.objects.order_by('-published_date')[:3]
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['about_me_records'] = AboutMe.objects.all()
return context
Now, you have one more queryset about_me_records to use in the template and iterate over.

Direct assignment to the forward side of a many-to-many set is prohibited. Use product.set() instead

i'm building a small webstore , in the product page i put the order form using FormMixin and TemplateView, when i submit the order i get a "Direct assignment to the forward side of a many-to-many set is prohibited. Use product.set() instead." error
Bellow you can check the code
Models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255, unique=True, )
description = models.TextField(max_length=1500)
class Meta:
verbose_name_plural = "categories"
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
nominal_price = models.PositiveIntegerField(verbose_name='prix normal',)
reduced_price = models.PositiveIntegerField(blank=True, null=True)
quantity = models.PositiveIntegerField(default=10)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
photo = models.ImageField(upload_to="img/products/", default="img/products/user_default.png")
def __str__(self):
return self.name
class Customer(models.Model):
full_name = models.CharField(max_length=150)
address = models.CharField(max_length=1500, null=True)
phone = models.IntegerField()
city = models.CharField(max_length=100)
email = models.EmailField(null=True)
class Order (models.Model):
product = models.ManyToManyField(Product, through='OrderProduct')
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
class OrderProduct(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
Views.py
class ProductDetailView(FormMixin, TemplateView):
model = Product
template_name = 'product.html'
form_class = OrderForm
def get_success_url(self):
return reverse('index')
def post(self, request, *args, **kwargs):
context = self.get_context_data()
form = OrderForm(request.POST)
if context['form'].is_valid():
product = get_object_or_404(Product, name=self.kwargs['product_name'])
customer = form.save()
Order.objects.create(product=product, customer=customer)
return super(TemplateView, self)
def get_context_data(self, **kwargs):
context = super(ProductDetailView, self).get_context_data(**kwargs)
context['product'] = Product.objects.get(name=self.kwargs['product_name'])
context['form'] = self.get_form()
return context
urls.py
path('', views.ProductListView.as_view(), name='index'),
Did i missed something
For handling many-to-many relations, you cannot directly set the product from Order. Also you would need to create the order first before you can set or add a product:
order = Order.objects.create(customer=customer)
order.product.add(product)

How do I display comments that are using a foreign key of another model in Django class based views?

I would like to list out the comments on my Post Detail page and wanted to see how I can connect a view to the specific comments for a given post?
Models.py
class Post(models.Model):
owner = models.ForeignKey(
Profile, null=True, blank=True, on_delete=models.SET_NULL)
title = models.CharField(max_length=200)
body = models.TextField()
Post_image = models.ImageField(
null=True, blank=True, default='default.jpeg')
create_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', kwargs={'pk': self.pk})
class Meta:
ordering = ['-create_date']
class Comment(models.Model):
owner = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
text = models.TextField()
create_date = models.DateTimeField(auto_now_add=True)
Views.py
class PostDetailView(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comment_list'] = Post.comment_set.all()
return context
You can access the detail object of the DetailView with self.object:
class PostDetailView(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comment_list'] = self.object.comment_set.order_by('create_date')
return context

How to use checkbox in form, i have in my model 1 field manytomanyfield

I need to show the category field in my template as a checkbox field.
forms.py
class PostUpdateForms(forms.ModelForm):
class Meta:
model = CreatePost
fields = ['title', 'img', 'category', 'content' ]
widgets = {
'title':forms.TextInput(attrs={'class':'form-control'}),
}
models.py
class Categories(models.Model):
category = models.CharField(verbose_name="Categoria", max_length=20)
class Meta:
verbose_name = 'Categoria'
verbose_name_plural = 'Categorias'
ordering = ['category']
def __str__(self):
return self.category
def custom_upload_to(instance, filename):
#old_intance = CreatePost.objects.get(pk=instance.pk)
#old_intance.img.delete()
return 'post/'+filename
class CreatePost(models.Model):
#user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="Usuario")
title = models.CharField(verbose_name="Titulo", max_length=100)
slug = models.CharField(max_length=200, blank=True)
content = models.TextField(verbose_name="Contenido", null=True, blank=True)
img = models.ImageField(upload_to=custom_upload_to, null=True, blank=False)
category = models.ManyToManyField(Categories)
created = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(CreatePost, self).save(*args, **kwargs)
class Meta:
verbose_name = 'Anime'
verbose_name_plural = 'Animes'
ordering = ['-created']

Django Queryset - Issue with retrieving data from 3rd model

I want to get the 'profilephoto' from the Profile model for each Review that a Product has but that requires the Review models profile_id which is already apart of a context. Is there any way to do this?
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
profilephoto = models.ImageField(default='profiles/default_profile.jpg', upload_to='profiles')
class Product(models.Model):
name = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
category = models.CharField(max_length=100)
releasedate = models.DateField()
description = models.TextField()
productphoto = models.ImageField(default='products/default_product.jpg', upload_to='products')
class Review(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.PositiveSmallIntegerField(default=1, validators = [MinValueValidator(1), MaxValueValidator(5)])
reviewtext = models.TextField()
views.py
class ProductDetailView(TemplateView):
# template_name = 'reviewApp/test.html'
template_name = 'reviewApp/product_detail.html'
def get_context_data(self, **kwargs):
prod = self.kwargs['pk']
context = super(ProductDetailView, self).get_context_data(**kwargs)
context['Products'] = Product.objects.filter(id=prod)
context['Reviews'] = Review.objects.filter(product=prod)
prof = Review.objects.only('profile_id')
context['Profiles'] = Profile.objects.filter(id__in=prof)
return context
class ProductDetailView(TemplateView):
# template_name = 'reviewApp/test.html'
template_name = 'reviewApp/product_detail.html'
def get_context_data(self, **kwargs):
prod = self.kwargs['pk']
context = super(ProductDetailView, self).get_context_data(**kwargs)
context['Product'] = Product.objects.get(id=prod)
context['Reviews'] = Review.objects.filter(product_id=prod)
profile_ids = Review.objects.values_list('profile_id', flat=True)
context['Profiles'] = Profile.objects.filter(id__in=profile_ids)
return context

Categories

Resources