I have articles combined by categories. Here are data models:
class Category(models.Model):
name = models.CharField(max_length=200, verbose_name='Наименование')
slug = models.SlugField(max_length=250, verbose_name='URL')
created = models.DateTimeField(auto_now_add=True, verbose_name='Добавлено')
objects = models.Manager()
class Meta:
ordering = ('name',)
verbose_name = 'категорию'
verbose_name_plural = 'Категории'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('main:article_list_by_category', args=[self.slug])
class Article(models.Model):
STATUS_CHOICES = (
('draft', 'Черновик'),
('published', 'Опубликовано'),
)
TYPE_ARTICLE_CHOICES = (
('Руководство', 'Руководство'),
('Инструкция', 'Инструкция'),
)
title = models.CharField(max_length=250, verbose_name='Заголовок')
slug = models.SlugField(max_length=250, unique_for_date='publish', verbose_name='URL')
type_article = models.CharField(max_length=15, choices=TYPE_ARTICLE_CHOICES, default='Инструкция',
verbose_name='Тип статьи')
category = models.ForeignKey(Category,
related_name='article',
on_delete=models.CASCADE, verbose_name='Категория')
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts', verbose_name='Автор')
body = RichTextUploadingField(verbose_name='Статья')
publish = models.DateTimeField(default=timezone.now, verbose_name='Опубликовано')
created = models.DateTimeField(auto_now_add=True, verbose_name='Добавлено')
updated = models.DateTimeField(auto_now=True, verbose_name='Обновлено')
status = models.CharField(max_length=12, choices=STATUS_CHOICES, default='draft', verbose_name='Статус')
tags = TaggableManager()
private = models.BooleanField(default=False, verbose_name='Приватная статья')
objects = models.Manager()
published = PublishedManager()
class Meta:
ordering = ('-publish',)
verbose_name = 'статью'
verbose_name_plural = 'Статьи'
index_together = (('id', 'slug'),)
indexes = [GinIndex(fields=['title'])]
def __str__(self):
return self.title
Here is the output template:
<div class="container my-container-style">
<div class="row">
<div class="col-md-3">
<h4 class="mb-4 category">Категории</h4>
<div id="sidebar">
<ul>
<li {% if not category %} class="selected" {% endif %}>
Все
</li>
{% for c in categories %}
<li {% if category.slug == c.slug %} class="selected" {% endif %}>
{{ c.name }}
</li>
{% endfor %}
</ul>
</div>
</div>
<div class="col-md-9">
{% if tag %}
<h2 class="tag_title">Статьи с тегами: "{{ tag.name }}"</h2>
{% endif %}
{% for articles in Article %}
<div class="article col-md-12">
<h2 class="article_title">{{ articles.title }}</h2>
<div class="article_info">
<span>Автор: {{ articles.author.first_name }} «{{ articles.author }}» {{ articles.author.last_name }}</span>
<span>Обновлено: {{ articles.updated|date:'d-m-Y' }}</span>
<span>Тип статьи: {{ articles.type_article }}</span>
</div>
<div class="article_body">
<p>{{ articles.body|safe|truncatewords:30 }}</p>
</div>
<div class="read_more">
<p class="mb-4"><a class="btn btn-secondary button_read back" href="{{ articles.get_absolute_url }}" role="button">Читать далее »</a></p>
</div>
</div>
{% endfor %}
{% include "pagination.html" with page=Article %}
</div>
</div>
</div>
I've found similar question (Django how hide empty category) but I can't hide a category with my own filter. How to properly hide a category with zero articles in it?
Related
TypeError at /vegetables/
get_object_or_404() got an unexpected keyword argument 'slug'
views.py
from django.shortcuts import render, get_object_or_404
from .models import Category
from .models import Product
def allProductCategory(request,c_slug=None):
c_page=None
products=None
if c_slug!=None:
c_page=get_object_or_404(Category,slug=c_slug)
products=Product.objects.all().filter(category=c_page,available=True)
else:
products=Product.objects.all().filter(available=True)
return render(request, 'category.html',{'category':c_page,'products':products})
urls.py
app_name='ecommerceapp'
urlpatterns = [
path('',views.allProductCategory,name='allProductCategory'),
path('<slug:c_slug>/',views.allProductCategory,name='products_by_category'),
]
Includes 2 tables-Category, Product
models.py
class Category(models.Model):
name = models.CharField(max_length=250,unique=True)
slug = models.SlugField(max_length=250,unique=True)
desc = models.TextField(blank=True)
image = models.ImageField(upload_to='category',blank=True)
class Meta:
ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return '{}'.format(self.name)
def get_url(self):
return reverse('ecommerceapp:products_by_category',args=[self.slug,])
class Product(models.Model):
name = models.CharField(max_length=250, unique=True)
slug = models.SlugField(max_length=250, unique=True)
desc = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
image = models.ImageField(upload_to='product', blank=True)
stock = models.IntegerField()
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('name',)
verbose_name = 'product'
verbose_name_plural = 'products'
def __str__(self):
return '{}'.format(self.name)
Base.html is created. header.html, navbar.html, footer.html are included in base.html. Other than these three a block content and endblock is created in base.html.
category.html
{% extends 'base.html' %}
{% load static %}
{% block metadescription %}
{% if category %}
{{ category.description|truncatewords:155 }}
{% else %}
Welcome to ZUPER Store where you can get everything.
{% endif %}
{% endblock %}
{% block title %}
{% if category %}
{{ category.name }} - ZUPER store
{% else %}
All that you need - ZUPER store
{% endif %}
{% endblock %}
{% block content %}
{% if category %}
<div>
<div>
<p>Our products</p>
</div>
</div>
{% endif %}
<div>
{% if category %}
<img src="{{category.image.url}}" alt="{{category.name}}">
</div>
<br>
<div>
<h1>{{category.name}}</h1>
<p>{{category.description}}</p>
</div>
{% else %}
<div>
<img src="{% static 'images/Banner.png' %}" alt="Our products" width="500px;" height="100px;">
</div>
<br>
<div>
<h1>Our product collections</h1>
<p>Dummy content</p>
</div>
{% endif %}
<div>
<div>
{% for product in products %}
<div>
<div>
<img src="{{product.image.url}}" alt="{{product.name}}">
<div>
<h4>{{product.name}}</h4>
<p>{{product.price}}</p>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
I'am getting this error when I click on the hyperlink vegetables and cotton dress.
I am currently working on a store made in Django and I have a problem because I have a model for Category as well as Subcategory. The problem is that I don't really know what I did wrong, because in the html file I try to call both categories and subcategories, but in each category all subcategories are displayed, instead of belonging to a specific category. I would like to ask for your help, and check, if files below are correctly written. Thanks in advance
models.py
from django.db import models
from django.urls import reverse
# Class model for category
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('selcorshop:product_list_by_category',
args=[self.slug])
# Class model for subcategory
class Subcategory(models.Model):
category = models.ForeignKey(Category,
related_name='category',
on_delete=models.CASCADE)
name = models.CharField(max_length=200,
db_index=True)
slug = models.SlugField(max_length=200,
db_index=True)
class Meta:
ordering = ('name',)
verbose_name = 'subcategory'
verbose_name_plural = 'subcategories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('selcorshop:product_list_by_subcategory',
args=[self.slug])
# Class model for product
class Product(models.Model):
subcategory = models.ForeignKey(Subcategory,
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.ImageField(upload_to='products/%Y/%m/%d',
blank=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
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('selcorshop:product_detail',
args=[self.id, self.slug])
views.py
from django.shortcuts import render, get_object_or_404
from .models import Category, Subcategory, Product
from cart.forms import CartAddProductForm
# View for product list in site
def product_list(request, category_slug=None, subcategory_slug=None):
category = None
categories = Category.objects.all()
subcategory = None
subcategories = Subcategory.objects.all()
products = Product.objects.filter(available=True)
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
products = products.filter(category=category)
return render(request,
'selcorshop/product/list.html',
{'category': category,
'categories': categories,
'subcategory': subcategory,
'subcategories': subcategories,
'products': products})
# View for single product
def product_detail(request, id, slug):
product = get_object_or_404(Product,
id = id,
slug = slug,
available = True)
# Add to cart button
cart_product_form = CartAddProductForm()
return render(request,
'selcorshop/product/detail.html',
{'product': product,
'cart_product_form': cart_product_form})
urls.py
from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static
app_name = 'selcorshop'
urlpatterns =[
path('', views.product_list, name='product_list'),
path('<slug:category_slug>/', views.product_list, name='product_list_by_category'),
path('<slug:subcategory_slug>/', views.product_list, name='product_list_by_subcategory'),
path('<int:id>/<slug:slug>/', views.product_detail, name='product_detail'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
list.html
{% extends "selcorshop/base.html" %}
{% load static %}
{% block title %}
{% if category %}{{ category.name }}{% else %}Produkty{% endif %}
{% endblock %}
{% block content %}
<div class="row">
<div id="sidebar" class="col-2">
<div class="d-flex flex-column flex-shrink-0 p-3 text-white bg-dark" style="width: 280px;">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-white text-decoration-none">
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="32" fill="currentColor" class="bi bi-list" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
</svg>
<span class="fs-4">Kategorie</span>
</a>
<hr>
<ul class="nav nav-pills flex-column mb-auto">
<li {% if not category %}class="nav-item" {% endif %}>
Wszystkie
</li>
<div class="dropdown">
**{% for c in categories %}
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<li {% if category.slug == c.slug %} {% endif %}>
{{ c.name }}
</li>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
{% for s in subcategories %}
<a class="dropdown-item" href="#">
<li {% if subcategory.slug == s.slug %} {% endif %}>
{{ s.name }}
</li>
</a>
{% endfor %}
</div>
{% endfor %}**
</div>
</ul>
<!-- <ul class="nav nav-pills flex-column mb-auto">-->
<!-- <li {% if not category %}class="nav-item" {% endif %}>-->
<!-- Wszystkie-->
<!-- </li>-->
<!-- {% for c in categories %}-->
<!-- <li {% if category.slug == c.slug %} {% endif %}>-->
<!-- {{ c.name }}-->
<!-- </li>-->
<!-- {% endfor %}-->
<!-- </ul>-->
</div>
</div>
<div id="main" class="product_list col-10">
<h2>{% if category %}{{ category.name }}{% else %}Produkty{% endif %}</h2>
{% for product in products %}
<div class="item">
<a href="{{ product.get_absolute_url }}">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static 'img/no_image.png' %}{% endif %}" alt="Obraz">
</a>
{{ product.name }}<br>
{{ product.price }} zł.
</div>
{% endfor %}
</div>
</div>
{% endblock %}
So after seeing your code I guess you want to create a dropdown menu in which all the subcategory list related to category open right so for that you can call it with related name which you pass in your subcategory model a use it in your HTML like that
{% for c in category_list %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-dark" href="#" id="navbarDarkDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false" style="font-weight:500">
<strong>{{ c.name }}</strong>
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDarkDropdownMenuLink">
{% for subcategory in c.category.all %}
<li><a class="dropdown-item" href="#">{{ subcategory.name }}</a>
{% endfor %}
</ul>
</li>
{% endfor %}
this has to solve your problem andd tell me if you still got any issue
models.py:
class Venue(models.Model):
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
title = models.CharField(max_length=300)
city = models.ForeignKey(City, on_delete=models.CASCADE)
address = models.CharField(max_length=300)
phone = models.CharField(max_length=20, default='')
email = models.CharField(max_length=100, default='')
site = models.CharField(max_length=100, default='')
facebook = models.CharField(max_length=100, default='')
instagram = models.CharField(max_length=100, default='')
content = models.TextField()
rating = models.DecimalField(default=10.0, max_digits=5, decimal_places=2)
created_date = models.DateTimeField(default=timezone.now)
approved_venue = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return f"{self.title}"
forms.py
class VenueForm(forms.ModelForm):
class Meta:
model = Venue
fields = [
'title',
'content',
'city',
'address',
'phone',
'email',
'site',
'facebook',
'instagram',
]
def __init__(self, *args, **kwargs):
super(VenueForm, self).__init__(*args, **kwargs)
self.fields['title'].label = "Име"
self.fields['content'].label = 'Описание'
self.fields['city'].label = 'Град'
self.fields['address'].label = 'Адрес'
self.fields['phone'].label = 'Телефон'
self.fields['email'].label = 'E-mail'
self.fields['site'].label = 'Сайт'
html render:
<form method="post" id="dialog_addVenue_part" enctype="multipart/form-data">
{% csrf_token %}
{% for hidden in postForm.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form %}
<div class="fieldWrapper">
<div class="errorcode{{field.html_name}}">
{{ field.errors }}
</div>
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
<div id="map" style="height: 500px;">
</div>
<div class="utf_addVenue_form">
<button type="submit" value="Изпрати">Изпрати</button>
</div>
</form>
Part of HTML with required fields:
<div class="fieldWrapper">
<div class="errorcodesite">
</div>
<label for="id_site">Сайт:</label> <input type="text" name="site" maxlength="100" required="" id="id_site">
</div>
<div class="fieldWrapper">
<div class="errorcodefacebook">
</div>
<label for="id_facebook">Facebook:</label> <input type="text" name="facebook" maxlength="100" required="" id="id_facebook">
</div>
I have not indicated anywhere that form should have "required" to all fields but they comes with it. So, Are Django model forms are required by default and how to set required to false for whole form?
Add blank=True to the fields you don't need to be required.
class Venue(models.Model):
. . .
title = models.CharField(max_length=300, blank=True)
. . .
I have created a Job model that contains Member and Manager info. It looks great imo. I created a class based view that translates the job if the user has one. Right now it's not showing. It just shows as a blank with an empty image file. I don't know what I did wrong or if I mistakenly used the wrong variables in the html file.
Here's my views.py:
from django.shortcuts import render
from django.views.generic import ListView, CreateView
from .models import Job
from profiles.models import User
# Create your views here.
class jobs(ListView):
model = Job
template_name = 'users/user_jobs.html'
context_object_name = 'jobs'
def get_queryset(self):
return Job.objects.filter(member__member=self.request.user)
class createjob (CreateView):
model = Job
fields = ['member','title', 'description', 'file'
My Models.py:
from django.db import models
from profiles.models import User
# Create your models here.
class Points (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
points = models.IntegerField(default=0, null=False)
def __str__(self):
return self.user.username
class Profile (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.png',upload_to='profile_pics')
def __str__(self):
return f'{self.user.username}Profile'
class Manager (models.Model):
name = models.CharField(max_length=30, blank=True, null=True)
manager = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.name
class Member (models.Model):
name = models.CharField(max_length=30, blank=True, null=True)
manager = models.ForeignKey(Manager, on_delete=models.CASCADE)
member = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.name
class Job (models.Model):
manager = models.OneToOneField(Manager, on_delete=models.CASCADE)
member = models.OneToOneField(Member, on_delete=models.CASCADE)
title = models.CharField(max_length=30, blank=False, null=False)
description = models.TextField()
datePosted = models.DateTimeField (auto_now = True)
file = models.FileField(null=True, blank=True,upload_to='job_files')
def __str__(self):
return self.title
And user_jobs.html:
{% extends "profiles/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img"src="{{ jobs.manager.profile.image.url}}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="#">{{ objects.job.Manager }}</a>
<small class="text-muted">{{jobs.datePosted|date:"F d, Y" }}</small>
</div>
<h2><a class="article-title" href="#">{{ jobs.title }}</a></h2>
<p class="article-content">{{ jobs.description }}</p>
</div>
</article>
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4"href="?page=1"> First</a>
<a class="btn btn-outline-info mb-4"href="?page={{ page_obj.previous_page_number }}"> Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-outline-info mb-4"href="?page={{ num }}"> {{ num }}</a>
{% elif num > page.obj.number|add:'-3' or num < page.obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4"href="?page={{ num }}"> {{ num }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4"href="?page={{ page_obj.next_page_number }}"> Next </a>
<a class="btn btn-outline-info mb-4"href="?page={{ page_obj.paginator.num_pages }}"> Last </a>
{% endif %}
{%endif%}
{% endblock content %}
TIA for the help guys.
you have to loop through the object list output in your list template to see the out put
{% for object in jobs %}
{{ object.title }}
{% endfor %}
I read the book 'Django By Example' and run the examples in chaper7.
But the results call "NoReverMatch at /"
NoReverseMatch at /
Reverse for 'product_detail' with arguments '(5, u'ironman')' and keyword arguments '{}' not found. 1 pattern(s) tried: ['(?P<id>[\\d+])/(?P<slug>[-\\w+])/$']
This is the models.py
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',)
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])
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True)
image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
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 = ('-created',)
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])
This is the urls.py
urlpatterns = [
url(r'^$', views.product_list, name='product_list'),
url(r'^(?P<category_slug>[-\w]+)/$', views.product_list, name='product_list_by_category'),
url(r'^(?P<id>\d+)/(?P<slug>[-\w+])/$', views.product_detail, name='product_detail'),
]
This is the views.py
def product_list(request, category_slug=None):
category = None
categories = Category.objects.all()
products = Product.objects.filter(available=True)
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
products = products.filter(category=category)
return render(request, 'shop/product/list.html', {'category': category, 'categories': categories, 'products': products})
def product_detail(request, id, slug):
product = get_object_or_404(Product,
id=id,
slug=slug,
available=True)
return render(request, 'shop/product/detail.html', {'product': product})
And this is the 'list.html' template where the error occurs.
{% extends "shop/base.html" %}
{% load static %}
{% block title %}
{% if category %}{{ category.name }}{% else %}Products{% endif %}
{% endblock %}
{% block content %}
<div id="sidebar">
<h3>Categories</h3>
<ul>
<li {% if not category %} class="selected" {% endif %}>
All
</li>
{% for c in categories %}
<li {% if category.slug == c.slug %} class="selected" {% endif %}>
{{ c.name }}
</li>
{% endfor %}
</ul>
</div>
<div id="main" class="product-list">
<h1>{% if category %}{{ category.name }}{% else %}Products{% endif %} </h1>
{% for product in products %}
<div class="item">
<a href="{{ product.get_absolute_url }}">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static 'img/no_image.png' %}{% endif %}">
</a>
{{ product.name }}<br>
${{ product.price }}
</div>
{% endfor %}
</div>
{% endblock %}
The error occurs at
<a href="{{ product.get_absolute_url }}">
-- line.
Why this error occurs??
It looks to me like you need to change your url pattern:
url(r'^(?P<id>\d+)/(?P<slug>[-\w+])/$', views.product_detail, name='product_detail')
perhaps to:
url(r'^(?P<id>\d+)/(?P<slug>[-\w]+)/$', views.product_detail, name='product_detail')
'+' does not function as a special character inside square brackets, so [-\w+] will only match a single character (alphanumeric or '-'), but you are passing multi-character strings like 'ironman'. [-\w]+ will match one or more characters.