Django Show Subcategories by Category Id - python

I have a problem (I think) with urls and views. So that, I have 3 categories, and each of them has 3 subcategories. I want to open subcategories when clicked on each category.
urls.py:
urlpatterns = [
path('', views.index),
url(r'^category/(?P<pk>\d+)$', views.category, name='category'),
]
views.py:
def category(request):
categories = Category.objects.all()
subcategories = SubCategory.objects.all()
return render(request, 'category.html', {'categories': categories, 'subcategories': subcategories}
base.html:
{% for category in categories%}
<a class="dropdown-item" href="{% url 'category' pk=category.pk %}">{{ category.name }}</a>
{% endfor %}
models.py
class Category(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
def __str__(self):
return self.name
class SubCategory(models.Model):
name = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
image_url = models.CharField(default=0, max_length=2000)
price = models.IntegerField(default=0)

urls.py
urlpatterns = [
path('', views.index),
url(r'^get_subcategory/(?P<pk>\d+)$', views.get_subcategory, name='get_subcategory'),
]
models.py(should like this)
class Category():
name=models.CharField()
class SubCategory():
name=models.CharField()
category = models.ForeignKey(Category)
views.py
def get_subcategory(request, pk):
category = Category.objects.get(id=pk)
subcategories = SubCategory.objects.filter(category=category)
return render(request, 'category.html', {'categories': categories, 'subcategories': subcategories}
html
{% for category in categories%}
<a class="dropdown-item" href="{% url 'YourAppName:get_subcategory' pk=category.id %}">{{ category.name }}</a>
{% endfor %}

Related

An error NoReverseMatch appears when I try to edit a post using UpdateView in Django

When I click on the update post link, an error appears: Reverse for 'post_detail' with no arguments not found. 1 pattern(s) tried: ['post/(?P[-a-zA-Z0-9_]+)$'].
My Post model looks like this:
class Post(models.Model):
title = models.CharField(max_length=200, verbose_name='Заголовок')
slug = AutoSlugField(populate_from=['title'])
title_image = models.ImageField(upload_to=user_img_directory_path, blank=True, verbose_name='Изображение')
description = models.TextField(max_length=500, verbose_name='Описание')
body = FroalaField(options={
'attribution': False,
}, verbose_name='Текст')
post_date = models.DateTimeField(auto_now_add=True, verbose_name='Дата публикации', db_index=True)
post_update_date = models.DateTimeField(auto_now_add=True, verbose_name='Дата обновления публикации')
post_status = models.BooleanField(default=True, verbose_name='Опубликовано')
class Meta:
ordering = ['-post_date']
def get_absolute_url(self):
return reverse('articles:post_detail', kwargs={'slug': self.slug})
def __str__(self):
return self.title
My DetailView and UpdateView classes in views.py:
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView
class PostDetail(DetailView):
model = Post
template_name = 'articles/post_detail.html'
context_object_name = 'post'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
class UpdatePost(UpdateView):
model = Post
template_name = 'articles/update_post.html'
fields = ['title', 'title_image', 'description', 'body']
My urls.py file:
from .views import PostsList, PostDetail, CreatePost, UpdatePost
app_name = 'articles'
urlpatterns = [
path('', PostsList.as_view(), name='posts_list'),
path('post/<slug:slug>', PostDetail.as_view(), name='post_detail'),
path('create/', CreatePost.as_view(), name='create_post'),
path('post/edit/<slug:slug>', UpdatePost.as_view(), name='update_post'),
]
update_post.html template looks like this:
{% extends 'layout/basic.html' %}
{% load static %}
{% load django_bootstrap5 %}
{% block content %}
<form method="post" class="form">
{% csrf_token %}
{{ form.media }}
{% bootstrap_form form %}
{% bootstrap_button button_type="submit" content="Обновить" %}
</form>
<a class="btn btn-outline-primary" href="{% url 'articles:post_detail' %}" role="button">Назад</a>
{% endblock %}
And update_post link in post_detail.html looks like this:
<a class="btn btn-outline-primary" href="{% url 'articles:update_post' post.slug %}" role="button">Обновить</a>
Please tell me how can I solve this problem?
Good morning, the problem is that the template cannot access the slug field. You have to inject the slug into context:
class UpdatePost(UpdateView):
model = Post
template_name = 'articles/update_post.html'
fields = ['title', 'title_image', 'description', 'body']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['slug'] = self.object.slug
return context

'Category' object is not iterable

I am new to programming
I have different categoriries in my django website, I created the model, view. but when I try to go to the localhost/category/categoryname, I get the error: "Category object is not iterable"
I appreciate your help in advance
#url.py
urlpatterns = [
path('', home, name='home'),
path('article/<slug:slug>', detail, name='detail'),
path('article', article, name='article'),
path('category/<slug:slug>', category, name='category')]
###############################################
#views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, JsonResponse, Http404
from .models import Article, Category
# Create your views here.
def home(request):
context = {
"articles": Article.objects.filter(status="Published")
}
return render(request, 'website/home.html', context)
def detail(request, slug):
context = {
"article": get_object_or_404(Article, slug=slug, status="Published")
}
return render(request, 'website/detail.html', context)
def article(request):
context = {
"articles": Article.objects.filter(status="Published"),
"category": Category.objects.filter(status=True)
}
return render(request, 'website/article.html', context)
def category(request, slug):
context = {
"category": get_object_or_404(Category, slug=slug, status=True)
}
return render(request, 'website/category.html', context)
###############################
#models.py
from django.db import models
from django.utils import timezone
# Create your models here.
class Category(models.Model):
title = models.CharField(max_length=300, verbose_name="Category Topic")
slug = models.SlugField(max_length=100, unique=True, verbose_name="Category Address")
status = models.BooleanField(default=True, verbose_name="Do you want to show?")
position = models.IntegerField(verbose_name="position")
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ['position']
def __str__(self):
return self.title
class Article(models.Model):
STATUS_CHOICES = (
('Draft', 'Draft'),
('Published', 'Published')
)
title = models.CharField(max_length=300)
slug = models.SlugField(max_length=100, unique=True)
category = models.ManyToManyField(Category, verbose_name="Category", related_name="articles")
description = models.TextField()
thumbnail = models.ImageField(upload_to="images")
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES)
class Meta:
ordering = ['-publish']
def __str__(self):
return self.title
######################
#category.html
{% for article in category.articles.all %}
<article class="entry" data-aos="fade-up">
<div class="entry-img">
<img src="{{ article.thumbnail.url }}" alt="" class="img-fluid">
</div>
<h2 class="entry-title">
{{ article.title }}
</h2>
<div class="entry-meta">
<ul>
<li class="d-flex align-items-center"><i class="icofont-user"></i>
John Doe</li>
<li class="d-flex align-items-center"><i class="icofont-wall-clock"></i>
<time>{{ article.publish }}</time></li>
<li class="d-flex align-items-center"><i class="icofont-tags"></i>
<ul class="tags">
{% for cat in article.category.all %}
{{ cat.title }}
{% endfor %}
</ul>
</li>
<li class="d-flex align-items-center"><i class="icofont-comment"></i>
12 Comments</li>
</ul>
</div>
<div class="entry-content">
{{ article.description|truncatewords:30}}
<div class="read-more">
Read More
</div>
</div>
</article><!-- End blog entry -->
{% endfor %}
your code is shallow- please do this to retrieve category list
def get_queryset(self):category =
get_object_or_404(Category, slug=self.kwargs.get("slug"))
return Post.objects.filter(category_id=category).order_by("-created")
you can use this to retieve category by specific list
Article.objects.filter(post__category__contains='politics'),
I changed the view and the problem solved:
def category(request, slug):
cat = get_object_or_404(Category, slug=slug, status=True)
context = {
"category": cat.articles.all()
}
return render(request, 'website/category.html', context)

How can i make post category list visible in all page in django

I am trying to make category name visible in every page. so for that I passed category model to every view. But here it is visible only in category_view.html page only.
I want to make it visible everywhere as I am listing out category name in navbar.
so far I did this
templates/navbar.html
<nav class="nav d-flex justify-content-between">
{%for name in category_name %}
{% for lst in post %}
<a class="p-2 text-muted" href="{% url 'posts:categoryview' slug=name.slug %}">{{name}}</a>
{% endfor %}
{% endfor %}
</nav>
views.py
from django.shortcuts import render, get_object_or_404,render_to_response
from .models import Post, Category
# Create your views here.
def posts_list(request):
query_list = Post.objects.all()
category_name = Category.objects.all()
context = {
"title" : "Latest Post",
"query_list": query_list,
"category_name": category_name
}
return render(request, "post_list.html", context)
def view_category(request, slug):
category = get_object_or_404(Category, slug=slug)
category_name = Category.objects.all()
return render_to_response('category_view.html', {
'category': category,
'post': Post.objects.filter(category=category).values(),
'category_name': category_name
})
urls.py
urlpatterns = [
path("", posts_list, name="list"),
path("<slug>", view_category, name="categoryview"),
]

Django QuerySet object has no attribute 'objects

I have problem with show product in category. (Products are show but when i click on category (tshirt) i have this problem AttributeError at /man/tshirt/
'QuerySet' object has no attribute 'objects
views.py
def product_list(request, category_slug=None):
category = None
categories = Category.objects.all()
products = Product.objects.filter(section='man', available=True)
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
products = products.objects.filter(category=category)
return render(request,
'shop/product/list.html',
{'category': category,
'categories': categories,
'products': products})
urls.py
urlpatterns = [
url(r'^$', views.main, name='main'),
url(r'^man/$', views.product_list, name='product_list'),
url(r'^man/(?P<category_slug>[-\w]+)/$',
views.product_list,
name='product_list_by_category'),
]
models.py
class Category(models.Model):
name = models.CharField(max_length=200,
db_index=True)
slug = models.SlugField(max_length=200,
db_index=True)
class Meta:
ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_list_by_category',
args=[self.slug])
list.html
{% extends "shop/base.html" %}
{% load static %}
{% block title %}VPW{% endblock %}
{% block content %}
<ul>
{% for c in categories %}
<li>
{{c.name}}
</li>
{% endfor %}
</ul>
{% for product in products %}
{{ product.name }}
{% endfor %}
{% endblock %}
You should change
products = products.objects.filter(category=category)
to
products = products.filter(category=category)
In short, you've already queried data at the objects level, thus the .objects identifier is no longer necessary or valid at this point in the code.
You can find more info here.

Django – create pages along with the objects using the same template

This is my first time here.
I'm stuck with a little problem in Django. I'm writing a webpage for a kennel and I have a model for dogs. These dogs appear on the front page after they have been created in admin page. I need it so that after clicking any dog picture on the front page, you could get to their profile(with the dog's name in the URL) that should use one template for each of them.
Here is my code in models, views and urls:
models.py
class dog(models.Model):
name = models.CharField(max_length=30, blank=False, null=True)
main_image = models.ImageField(upload_to='dogs', blank=False, null=True)
MALE = 'ML'
FEMALE = 'FM'
gender_list = (
(MALE, 'male'),
(FEMALE, 'female'),
)
gender = models.CharField(max_length=2, choices=gender_list, default='gender')
description = models.TextField(max_length=500, blank=False, null=True)
birthday = models.DateField(default=datetime.today, blank=True)
slug = AutoSlugField(populate_from='name')
views.py
def home(request):
dog_list = list(dog.objects.all())
template = 'home.html'
return render(request, template, {'dogs' : dog_list})
def dog_view(request, slug):
dog_view = get_object_or_404(dog, slug=slug)
return render(request, 'profile.html', {'dog_view' : dog_view})
urls.py
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^dogs/(?P<slug>[-\w]+)/$', views.dog_view, name='profile'),
url(r'^mating/', views.mating_list, name='mating'),
url(r'^admin/', admin.site.urls),
]
home.html
{% for dog in dogs %}
<a href="{% url 'profile' %}{{ dog.name }}">
<div class="col-sm-4">
<img class="img-circle img-responsive img-center" src="{{ dog.main_image.url }}" alt="">
<h2 align=center>{{ dog.name }}
<p>{{ dog.description }}</p>
</div>
{% endfor %}
I feel that it should be something very easy, although I searched over the internet and couldn't find how it is possible to have pages be automatically created along with the dog-objects.
Thank you very much in advance.
Try this:
views.py
def home(request):
dog_list = dog.objects.all()
template = 'home.html'
return render(request, template, {'dogs' : dog_list})
def dog_view(request, slug):
dog_view = get_object_or_404(dog, slug=slug)
return render(request, 'profile.html', {'dog_view' : dog_view})
home.html
{% for dog in dogs %}
{{ dog.name }}
<div class="col-sm-4">
<img class="img-circle img-responsive img-center" src="{{ dog.main_image.url }}" alt="">
<h2 align=center>{{ dog.name }}
<p>{{ dog.description }}</p>
</div>
{% endfor %}
urls.py
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^dogs/(?P<slug>[-\w]+)/$', views.dog_view, name='profile'),
url(r'^mating/', views.mating_list, name='mating'),
url(r'^admin/', admin.site.urls),
]

Categories