Show all articles from specific category [django] - python

I want show all Articles from specific category in my template 'category_articles.list.html' at the link: path('category/<name_of_category_SLUG>/'
I have:
URLS
urlpatterns = [
path('show/<int:pk>/<slug:slug>', ArticleDetailView.as_view(), name='article_detail'),
path('all/', AllArticlesListView.as_view(), name='all_articles_list'),
path('category/<slug:slug>/', CategoryArticlesList.as_view(), name='category_articles_list'),
]
MODELS
class Created(models.Model):
created_on = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
abstract = True
class ArticleCategory(Created):
category_name = models.CharField(max_length=128)
slug = models.SlugField(null=False, unique=False)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.category_name)
return super().save(*args, **kwargs)
def __str__(self):
return self.category_name
class Meta:
verbose_name_plural = 'Article categories'
class Article(Created):
title = models.CharField(max_length=120)
author = models.ForeignKey(User, on_delete=models.CASCADE)
snippet = models.TextField(null=False) # ustawić max_lenght
body = RichTextField(null=False)
category = models.ManyToManyField(ArticleCategory, related_name='articles') # TODO: ustawić on_delete
image = models.ImageField(blank=True, null=True, upload_to='article_image/')
slug = models.SlugField(null=False, unique=False)
def save(self, *args, **kwargs): # opisać tą funckję
if not self.slug:
self.slug = slugify(self.title)
return super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('news:article_detail', kwargs={'pk': self.pk, 'slug': self.slug})
def article_categories(self):
# zwraca nam wszystkie kategorię artykułu w stringu
return ", \n".join([x.category_name for x in self.category.all()])
def __str__(self):
return f"{self.title}"
class Meta:
verbose_name_plural = 'Articles'
VIEWS
class CategoryArticlesList(DetailView):
template_name = 'news/category_articles_list.html'
model = ArticleCategory
class AllArticlesListView(ListView):
template_name = 'news/articles_list.html'
model = Article
paginate_by = 2
def get_queryset(self):
return self.model.objects.all().order_by('-created_on')
class ArticleDetailView(DetailView):
template_name = 'news/article_detail.html'
model = Article
ARTICLES_LIST.HTML template
ALL NEWS
{% if object_list %}
{% for article in object_list %}
TITLE: {{ article.title }}
CATEGORY_iterator:
{% for category in article.category.iterator %}
{{ category | upper}}
{% endfor %}<br>
ARTICLE_DETAIL.HTML template
ONE SPECIFIC NEWS
<h3>TITLE: {{ article.title }}</h3>
<a href="{% url 'news:article_detail' pk=article.pk slug=article.slug %}">
{% url 'news:article_detail' pk=article.pk slug=article.slug %}</a> <br>
ID:
{{ article.id }} <br>
AUTHOR:
{{ article.author.username }} <br>
CATEGORY_iterator:
{% for category in article.category.iterator %}
{{ category | upper}}
{% endfor %}<br>
finally....
CATEGORY_ARTICLES_LIST.HTMLtemplate
ALL ARTICLES FROM CATEGORY: {{ articlecategory.category_name | upper }}
I don't know how put all articles to ARTICLE_DETAIL.HTML template...

You can iterate all articles from the reverse relation:
articlecategory.articles.all
I am not sure if you can use that in django templates and if it needs to be used with or without the "()".

Related

how to show avaliable sizes of clothes on the form? Django

I'm developing online clothing store on Django. Now I faced the issue: I have a form which helps user to add to his cart some clothes. I need to show which sizes of this clothes are avaliable. To do this, I need to refer to the database. But how to do it from the form?
models.py:
from django.db import models
from django.urls import reverse
from multiselectfield import MultiSelectField
class Category(models.Model):
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=True)
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_list_by_category',
args=[self.slug])
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True)
image = models.FileField(blank=True, upload_to=get_upload_path)
SIZE_CHOICES = (('XXS', 'XXS'),
('XS', 'XS'),
('S', 'S'),
('M', 'M'),
('XL', 'XL'),
('XXL', 'XXL'))
sizes = MultiSelectField(choices=SIZE_CHOICES,
max_choices=6,
max_length=17)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField()
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('name',)
index_together = (('id', 'slug'),)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_detail',
args=[self.id, self.slug])
my form:
forms.py
from django import forms
PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(1, 21)]
class CartAddProductForm(forms.Form):
quantity = forms.TypedChoiceField(choices=PRODUCT_QUANTITY_CHOICES, coerce=int)
update = forms.BooleanField(required=False, initial=False, widget=forms.HiddenInput)
# size = ??
the view which uses this form:
views.py
def product_detail(request: WSGIRequest, product_id: int, product_slug: str) -> HttpResponse:
product = get_object_or_404(Product,
id=product_id,
slug=product_slug,
available=True)
cart_product_form = CartAddProductForm()
return render(request, 'shop/product/detail.html', {'product': product,
'cart_product_form': cart_product_form})
shop/product/detail.html:
{% extends "shop/base.html" %}
<head>
<meta charset="UTF-8">
<title>Detail</title>
</head>
<body>
{% block content %}
<br>
<b>{{ product.name }} </b> <br>
<i>{{ product.description }} </i> <br>
{{ product.price }} <br>
<img src="{{ product.image.url }}" width="300" height="500"> <br>
Available sizes: <br>
{{ product.sizes }}<br>
<form action="{% url "cart:add_to_cart" product.id %}" method="post">
{{ cart_product_form }}
{% csrf_token %}
<input type="submit" value="Add to cart">
</form>
{% endblock %}
</body>
I tried to create a function which gets avaliable sizes and send to the form:
forms.py
def get_sizes(product: Product):
return product.sizes
But to do this I need to refer to the Product from the form, I don't know how to do it.
How about dividing each clothes by size(with quantity)? Clothes with different size can be treated as different product.
product
ID
name
image
description
price
...
1
jean
a.jpg
good jean
12345
...
size
ID
product_id
size
quantity
...
1
1
xxxl
12345
...
2
1
xxl
1234
...
3
1
xl
123
...
If quantity is greater than 0, that size of clothes is available.
my solution is:
forms.py
from django import forms
from django.forms import ModelForm
from shop.models import Product
class CartAddProductForm(ModelForm):
class Meta:
model = Product
fields = ['sizes']
def __init__(self, pk, *args, **kwargs):
super(CartAddProductForm, self).__init__(*args, **kwargs)
sizes = tuple(Product.objects.get(pk=pk).sizes)
sizes_list = []
for item in sizes:
sizes_list.append((item, item))
self.fields['sizes'] = forms.ChoiceField(choices=sizes_list)
when I create the form, I pass the pk:
views.py
product = get_object_or_404(Product,
id=product_id,
slug=product_slug,
available=True)
pk = product.pk
cart_product_form = CartAddProductForm(instance=product, pk=pk)

Django queryset filter based on slug

I want to put a filter on a page which shows videos selecting an album shows up on album page not all the videos but my current filter is showing all the published videos. I couldn't find a way to put a filter based on slug that if an album's slug is matching with the current url then shows the video selecting that album. For example:- Videos created by Gaurav should only visible on Gaurav’s album not anyone else. I am all confused help me.
models.py
from django.db import models
from django.urls import reverse
STATUS = (
(1, "Publish"),
(0, "Draft")
)
class WatchCategory(models.Model):
title = models.CharField(max_length=20)
slug = models.SlugField(max_length=2000, unique=True)
def __str__(self):
return self.title
class Genre(models.Model):
title = models.CharField(max_length=20)
slug = models.SlugField(max_length=2000, unique=True)
def __str__(self):
return self.title
class Album(models.Model):
title = models.CharField(max_length=2000)
slug = models.SlugField(max_length=2000, unique=True)
image = models.CharField(max_length=2000, blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('Watch:album', kwargs={
'slug': self.slug
})
class Video(models.Model):
title = models.CharField(max_length=2000)
slug = models.SlugField(max_length=2000, unique=True)
thumbnail = models.CharField(max_length=2000, unique=True)
updated_on = models.DateTimeField(auto_now=True)
file = models.CharField(max_length=2000)
time = models.CharField(max_length=2000, blank=True)
about = models.TextField(blank=True)
category = models.ManyToManyField(WatchCategory)
album = models.ManyToManyField(Album)
genre = models.ManyToManyField(Genre)
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=1)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('Watch:video', kwargs={
'slug': self.slug
})
views.py
class Album(ListView):
queryset = Video.objects.filter(status=1).order_by('-created_on')
template_name = 'Watch/album.html'
paginate_by = 6
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = 'Explore & Watch your favourite'
return context
album.html
{% extends "Watch/layout.html" %}
{% load static %}
{% block content %}
<div class="video-block section-padding">
<div class="row">
{% for video in video_list %}
<div class="col-xl-3 col-sm-6 mb-3">
<div class="video-card">
<div class="video-card-image">
<a class="play-icon" href="{% url 'Watch:video' video.slug %}"><i class="fas fa-duotone fa-circle-play"></i></a>
<img class="img-fluid" src="{{ video.thumbnail }}" alt="">
<div class="time">{{ video.time }}</div>
</div>
<div class="video-card-body">
<div class="video-title">
{{ video.title }}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}

How do i limit the numbers if comment to be displayed

I have multiple comments on my homepage, how do i limit the comment to be displayed on a post. Like, i have 10 comments and i want to display only 2 comments.
class Image(models.Model):
imageuploader_profile = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, null=True, blank=True)
first_upload_image = models.FileField(upload_to ='picmate',null=True, blank=True)
second_upload_image = models.FileField(upload_to ='picmate',null=True, blank=True)
image_caption = models.CharField(max_length=700)
date = models.DateTimeField(auto_now_add=True, null= True)
class Meta:
verbose_name = 'Image'
verbose_name_plural = 'Images'
ordering = ['-date']
def __str__(self):
return self.image_caption
class Comments (models.Model):
comment_post = models.TextField()
author = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, null=True, blank=True)
commented_image = models.ForeignKey('Image', on_delete=models.CASCADE, related_name='comments')
date = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Comment'
verbose_name_plural = 'Comments'
ordering = ['-date']
def __str__(self):
return self.author.__str__()
def home(request):
all_images = Image.objects.filter(imageuploader_profile=request.user.id)
users = User.objects.all()
next = request.GET.get('next')
if next: return redirect(next)
context = {
'all_images': all_images,
'users': users,
}
return render(request,'home.html', context,)
#login_required
def comments(request, id):
post = get_object_or_404(Image,id=id)
# current_user = request.user
print(post)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.author = request.user
comment.commented_image = post
comment.save()
return redirect('/')
else:
form = CommentForm()
all_comments = Comments.objects.filter(
author=request.user.id,
commented_image=post,
)
{% for comment in post.comments.all %}
<div class="mb-1" style="padding-bottom:-10px;position:relative;top:-10px">
<div class="truncate card-meta dark-grey-text" style="">
<a href="#" class="username dark-grey-text text-lowercase">
{{ comment.author }}</a> {{ comment.comment_post }}
</div>
</div>
{% endfor %}
You can use the django template tag slice
{% for comment in post.comments.all|slice:":2" %}
{{ comment.author }}
{% endfor %}

How to rendering to html in the viewsets in Django Rest Framework

models.py
class MyVideo(models.Model):
title = models.CharField(max_length=100, null=True, default='')
seotitle = models.CharField(max_length=100, null=True, default='')
keywords = models.CharField(max_length=150, null=True, default='')
status = models.IntegerField(default=1)
serializers.py
class MyVideoSerializer(serializers.ModelSerializer):
class Meta:
model = MyVideo
fields = '__all__'
views.py
class My(viewsets.ModelViewSet):
queryset = MyVideo.objects.all()
serializer_class = MyVideoSerializer
renderer_classes = (JSONRenderer, TemplateHTMLRenderer,)
template_name = "my.html"
def get(self, request, *args, **kwargs):
# ??????
def get_query(self):
# ??????
urls.py
urlpatterns = [
path('my/', views.My), # ???????? anything wrong here?
]
my.html
<html><body>
<h1>My video</h1>
<ul>
{% for d in data %}
<li>{{ d.title }}</li> # ?????? anything wrong here?
<li>{{ d.seotitle }}</li>
<li>{{ d.keywords }}</li>
{% endfor %}
</ul>
</body></html>
I have a MyVideo model which store several videos record in the database. What I wanna implement is that to display the information of those videos through the my.html.
e.g. http://127.0.0.1:8000/my/103 can access the video which id=103, and on this page display its fields (title, seotitle, keywords, etc.).
Any nice implementation or suggestion? Thanks!
**UPDATE
<html><body>
<h1>My video</h1>
<ul>
{{ data }}
</ul>
</body></html>
from django.shortcuts import render
class My(viewsets.ModelViewSet):
queryset = MyVideo.objects.all()
serializeddata = MyVideoSerializer(queryset,many=true)
renderer_classes = (JSONRenderer, TemplateHTMLRenderer,)
template_name = "my.html"
def get(self, request, *args, **kwargs):
return render_to_response(template_name, {'data': serializeddata.data})
#or use below
#return render(
#request,
#template_name=template_name,
#{'data': serializeddata}
#)
def get_query(self):
# ??????
UPDATE
models.py
"""
Definition of models.
"""
from django.db import models
# Create your models here.
class MyVideo(models.Model):
title = models.CharField(max_length=100, null=True, default='')
seotitle = models.CharField(max_length=100, null=True, default='')
keywords = models.CharField(max_length=150, null=True, default='')
status = models.IntegerField(default=1)
serializers.py
from rest_framework import serializers
from app.models import MyVideo
class MyVideoSerializer(serializers.ModelSerializer):
class Meta:
model = MyVideo
fields = '__all__'
my.html
<html><body>
<h1>My video</h1>
<ul>
{% for d in data %}
<li>Title: {{ d.title }}</li>
<li>SEO Title:{{ d.seotitle }}</li>
<li>KeyWords {{ d.keywords }}</li>
{% endfor %}
</ul>
</body></html>
views.py
def my(request):
"""Renders the contact page."""
assert isinstance(request, HttpRequest)
queryset = MyVideo.objects.all()
serializer_class = MyVideoSerializer(queryset,many=True)
#datan = {"title":"Test Title"}
return render(
request,
'app/my.html',
{
'data':serializer_class.data,
}
)
NOTE: You can add if(request.method == GET): elif(request.method == POST)
OUTPUT:

Getting ManyToMany field values in template

i got a problem with getting ManyToMany field values in template, here is the code:
models.py
class Client(models.Model):
name = models.CharField(max_length=18,help_text='Nazwa firmy klienta, musi być unikalna', verbose_name='Klienci')
slug = models.SlugField(max_length=255,help_text="Wartość sugerowana automatycznie na podstawie nazwy", unique=True, verbose_name='Odnośnik')
iconwhite = models.ImageField(upload_to='iconswhite', verbose_name='ikona na białym tle', blank=True)
class Meta:
ordering = ['name']
verbose_name = "Klient"
def __str__(self):
return self.name
def __unicode__(self):
return self.name
def get_absolute_url(self):
return '/clients/%s/' % self.slug
models.py
class Projects(models.Model):
def get_picture_path(instance, filename):
return os.path.join('picture', str(instance.id), filename)
client = models.ManyToManyField(Client, verbose_name='Klient')
title = models.CharField(max_length=255, verbose_name='Tytuł projektu')
slug = models.SlugField(max_length=255, unique=True, verbose_name='Odnośnik')
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='d')
picture = models.ImageField(upload_to=get_picture_path, blank=True, null=True, help_text='Miniatura widoczna na str głównej oraz w galerii projektow')
class Meta:
verbose_name = "Projekt"
def __str__(self):
return self.title
def __unicode__(self):
return self.title
def get_absolute_url(self):
return '/projects/' + self.slug + '/'
index.html
<div class="grid_4">
<div class="container_img">
<div><img src="site_media/media/{{i.picture}}" /></div>
<div class="client_icon">
{% for client in projects.client.all %}
<img src="site_media/media/{{client.iconwhite}}" />
{% endfor %}
</div>
</div>
<div class="project_description">
<p class="projects_title">{{ i.title }}</p>
<p class="projects_description">{{ i.description|safe|removetags:"p br div"|truncatewords:9 }} <span>see more »</span></p>
</div>
</div>
I checked other similar topics, dunno what am i missing here :(
If i is the variable holding an individual project (judging by the context in your HTML), you'd need:
{% for client in i.client.all %}
{{ client }}
{% endfor %}

Categories

Resources