I want to use reverse in the model to back a URL, which has three slugs.
But it gives me an error.
my URL is like this:
site.com/category/slug/slug/slug ...>
site.com/category/mobile/nokia/n95
Error:
'ForwardManyToOneDescriptor' object has no attribute 'slug'
Model:
from Django.db import models
from Django.shortcuts import reverse
class Category(models.Model):
name = models.CharField(max_length=150)
slug = models.SlugField(unique=True, max_length=200)
child_category = models.ForeignKey('self', max_length=150, null=True, blank=True, on_delete=models.CASCADE)
is_child = models.BooleanField(default=False)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:brands', args=[self.slug])
class Product(models.Model):
category = models.ManyToManyField(to=Category, related_name='products')
name = models.CharField(max_length=150)
slug = models.SlugField(unique=True, max_length=200)
description = models.TextField()
class Meta:
ordering = ('name', 'available',)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_details', self.category.model.slug, self.category.model.child_category.slug, self.slug)
URL:
from Django.urls import path
from Shop import views
app_name = 'shop'
urlpatterns = [
path('<slug:brands_slug>/', views.brands, name='brands'),
path('<slug:brands_slug>/<slug:product_slug>/', views.products, name='products'),
path('<slug:brands_slug>/<slug:product_slug>/<slug:product_details>/', views.details_products, name='product_details'),
]
View:
def details_products(request, brands_slug, product_slug, product_details):
details = Product.objects.filter(category__child_category__slug=brands_slug, category__slug=product_slug, slug=product_details)
context = {'details': details}
return render(request, 'shop/product_details.html', context=context)
change your path to this.
path('category/<slug:brands_slug>/<slug:product_slug>/<slug:product_details>/', views.details_products, name='product_details'),
Related
models.py:
from django.db import models
from django.urls import reverse
class Category(models.Model):
category_id = models.AutoField
category_name = models.CharField(max_length=50, default="")
desc = models.CharField(max_length=1000)
slug = models.SlugField(max_length=20)
image = models.ImageField(upload_to='onlinePizza/images', default="")
def get_url(self):
return reverse('category', args=[self.slug])
def __str__(self):
return self.category_name
class Product(models.Model):
product_id = models.AutoField
product= models.CharField(max_length=50)
category = models.ForeignKey(Category, default='', null=True, on_delete=models.CASCADE)
desc = models.CharField(max_length=1000)
image = models.ImageField(upload_to='onlinePizza/image', default="")
def __str__(self):
return self.product
This is my views.py file. I show error at:
bestseller = Product.objects.filter(product__category__icontains='BestSeller')
views.py:
from django.shortcuts import render
from . models import Category, Product, Deal
from math import ceil
def index(request):
bestseller = Product.objects.filter(product__category__icontains='BestSeller')
context = {'bestseller':bestseller}
return render(request, 'onlinePizza/index.html', context)
I want to Bestseller category product at index.html
I use Django 4 and pyhton 3.9
You can't use CharField as a ForeignKey.
It should be like this:
bestseller = Product.objects.filter(category__category_name ='BestSeller')
Or like this (the same logic):
best_seller_category = Category.objects.get(category_name = "BestSeller")
bestseller = Product.objects.filter(category=best_seller_category)
This will output all Products in category with name BestSeller.
I am trying to return all courses from the database to my course url and i got this error
NoReverseMatch at /course/
Reverse for 'course_detail' not found. 'course_detail' is not a valid view function or pattern name.
here is my code
class Courses(models.Model):
category = models.ForeignKey(Category, related_name='courses', on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=100)
description = models.TextField()
cover = models.ImageField(blank=True, null=True, upload_to="courses_cover/")
slug = models.SlugField()
# Courses content
content_url = models.URLField(blank=True, null=True)
content_file = models.FileField(blank=True, null=True)
price = models.PositiveIntegerField(default=1)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('courses:course_detail', args=[self.id, self.slug])
def price_display(self):
return "{0:.2f}".format (self.price / 100)
code for the views.py
def course_list(request, category_slug=None):
category = None
categories = Category.objects.all()
courses = Courses.objects.filter(available=True)
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
courses = courses.filter(category=category)
return render(request,'courses/content/list.html', {'category': category, 'categories': categories, 'courses': courses})
def course_detail(request, id, slug):
course = get_object_or_404(Courses, id=id, slug=slug, available=True)
return render(request, 'courses/content/detail.html', {'course': course})
code for the course urls
app_name = "courses"
urlpatterns = [
path('', views.course_list, name='course_list'),
Have you declared your namespace in your main urls.py? Or have you declared course where it should have been courses plural?
path('courses/', include('courses.urls', namespace='courses')),
I'm trying to create a simple car dealership app and i'm stuck. I have searched days and i have tried so many times to fix this but i can't. What i'm doing wrong i don't know and my brain is not working anymore. Thanks for help.
Error:
NoReverseMatch at /
Reverse for 'car_detail' with keyword arguments '{'slug': '2021-ram-1500-trx-crew-cab-4x4-57-box'}' not found. 1 pattern(s) tried: ['(?P<id>[0-9]+)/(?P<slug>[-a-zA-Z0-9_]+)$']
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 3.2.8
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'car_detail' with keyword arguments '{'slug': '2021-ram-1500-trx-crew-cab-4x4-57-box'}' not found. 1 pattern(s) tried: ['(?P[0-9]+)/(?P[-a-zA-Z0-9_]+)$']
Exception Location: C:\Users*\Desktop\Testdealer\envdealer\lib\site-packages\django\urls\resolvers.py, line 694, in _reverse_with_prefix
Python Executable: C:\Users*\Desktop\Testdealer\envdealer\Scripts\python.exe
Python Version: 3.9.7
Models.py:
from django.db import models
import datetime
from django.urls import reverse
class Car(models.Model):
brand = models.CharField(max_length=100)
CATEGORY = (
('New', 'New'),
('Used', 'Used')
)
slug = models.SlugField(max_length=200, null=True, unique=True)
category = models.CharField(max_length=50, choices=CATEGORY)
image_main = models.ImageField(upload_to='images')
body_style = models.CharField(max_length=100, blank=True)
engine = models.CharField(max_length=100, blank=True)
stock_number = models.IntegerField(blank=True, null=True)
mpg = models.CharField(max_length=100, blank=True)
exterior_color = models.CharField(max_length=100, blank=True)
interior_color = models.CharField(max_length=100, blank=True)
drivetrain = models.CharField(max_length=100, blank=True)
mileage = models.IntegerField(blank=True, null=True)
sold = models.BooleanField(default=False, blank=False)
transmission = models.CharField(max_length=50, blank=True)
YEAR_CHOICES = [(r, r) for r in range(1940, datetime.date.today().year+1)]
year = models.IntegerField(
('year'), choices=YEAR_CHOICES, default=datetime.datetime.now().year)
power = models.IntegerField()
fuel = models.CharField(max_length=50, blank=True)
price = models.CharField(max_length=10, blank=True)
description = models.TextField()
date = models.DateField()
def __str__(self):
return self.brand
def get_absolute_url(self):
return reverse('car_detail', kwargs={'slug': self.slug})
# def get_absolute_url(self):
# return reverse('car_detail', kwargs={
# 'car_id': self.id
# })
class CarImage(models.Model):
"""
The Product Image table.
"""
name = models.CharField(max_length=200, blank=True)
car = models.ForeignKey(
Car, on_delete=models.CASCADE, related_name="car_image")
image = models.ImageField(
verbose_name="image",
help_text="Upload a product image",
upload_to="images/",
default="images/default.png",
)
alt_text = models.CharField(
verbose_name="Alturnative text",
help_text="Please add alturnative text",
max_length=255,
null=True,
blank=True,
)
class Meta:
verbose_name = "Car Image"
verbose_name_plural = "Car Images"
def __str__(self):
return self.name
Views.py:
from django.shortcuts import render, get_object_or_404
from .models import Car, Dealer, CarImage
from django.core.mail import send_mail
def car_detail(request, id, slug):
cars = Car.objects.get(pk=id)
images = CarImage.objects.filter(car_id=id)
context = {'cars': cars, 'images': images}
return render(request, 'car_detail.html', context)
Urls.py:
from django.contrib import admin
from django.urls import path
from django.conf.urls.static import static
from django.conf import settings
from cars import views
..........
path('<int:id>/<slug:slug>', views.car_detail, name="car_detail"),
The .get_absolute_url() [Django-doc] of the Car model only specifies the slug, not the id parameter:
class Car(models.Model):
# ⋮
def get_absolute_url(self):
# add id to the context ↓
return reverse('car_detail', kwargs={'id': self.pk, 'slug': self.slug})
I have some models like this:
class Category(models.Model):
class Meta:
ordering = ['name']
name = models.CharField(max_length=100)
text = models.TextField(blank=True)
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Tool(models.Model):
name = models.CharField(max_length=30, null=True, default='')
url = models.URLField(max_length=250, null=True, default='')
image_url = models.URLField(max_length=250, null=True, default='', blank=True)
about = models.TextField(default='', null=True, blank=True)
tags = models.ManyToManyField( Tag, related_name="tools" , blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True,null=True, related_name="category1")
altcategory = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True,null=True, related_name="category2")
And everything seem ok, except when I go to add a tag to a Tool in the Admin screens.
I can create a Tool and Tag but when I select a tag in the taglist in the Admin screens and Save I get:
The above exception (syntax error at or near "ON" LINE 1: ...ls_tool_tags" ("tool_id", "tag_id") VALUES (1, 2) ON CONFLIC... ^ ) was the direct cause of the following exception:
with the sql:
('INSERT INTO "tools_tool_tags" ("tool_id", "tag_id") VALUES (%s, %s) ON '
'CONFLICT DO NOTHING')
The DEBUG screen is saying the error is at "tag_id", is strange...
I hope it's not a version thing, since I'm using Heroku and have been really impressed with how everything "just works". My Django version is '3.0.4' and Postgres 12.2.
I don't think ManyToMany works out of the box.
So I had to create a "through" model... and change the admin form to this...
models.py
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.auth.models import User
from django.utils.html import format_html
from django.contrib.contenttypes.models import ContentType
class Category(models.Model):
class Meta:
ordering = ['name']
name = models.CharField(max_length=100)
text = models.TextField(blank=True)
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Tool(models.Model):
name = models.CharField(max_length=30, null=True, default='')
url = models.URLField(max_length=250, null=True, default='')
image_url = models.URLField(max_length=250, null=True, default='', blank=True)
about = models.TextField(default='', null=True, blank=True)
tags = models.ManyToManyField(
Tag,
through="PageTags",
through_fields=('tool', 'tag'))
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True,null=True, related_name="category1")
altcategory = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True,null=True, related_name="category2")
def _get_thumbnail(self):
return format_html(u'<img src="{}" width="150"/>', self.image_url)
_get_thumbnail.allow_tags = True
def _get_link(self):
return format_html(u'<a href="{}" target="_blank"/>{}</a>', self.url, self.url)
_get_link.allow_tags = True
def __str__(self):
return self.name + ": " + self.url
class PageTags(models.Model):
tag = models.ForeignKey(Tag , on_delete=models.CASCADE, )
tool= models.ForeignKey(Tool , on_delete=models.CASCADE, )
amount = models.IntegerField(default=0)
... and admin.py to this...
from django.contrib import admin
from django.contrib.admin import TabularInline
#from django.contrib.contenttypes.admin import GenericTabularInline
from django.utils.html import format_html_join
from django.utils.safestring import mark_safe
from .models import Tool, Category, Tag, PageTags
class PageTagsInline(admin.TabularInline):
model = PageTags
extra = 1
class ToolAdmin(admin.ModelAdmin):
#fields = ('name', )
list_display = ('name','_get_link','category','altcategory', "_get_thumbnail", )
list_filter = ('category',)
search_fields = ['name', "about"]
filter_horizontal = ('tags',)
inlines = [PageTagsInline,]
admin.site.register(Tag)
admin.site.register(Category)
admin.site.register(Tool, ToolAdmin)
And the interface is different, not like the permissions widgets, but OK... at least not bombing the admin.
I'm new in Django and can't find a solution for my problem.
How to make a dynamic URL tree in Django like - site.com/{categoryName}/{itemName}/
Now I have this URL tree:
site.com/item/{itemSlug}/
site.com/category/{itemCategorySlug}/
But I need:
site.com/{itemCategorySlug}/{itemSlug}/
How can I crate this URL tree without installing 3rd party plugins?
Models
from django.db import models
from django.shortcuts import reverse
from services.slug.generator import generate_slug
class Category(models.Model):
name = models.CharField(max_length=400, unique=True)
description = models.TextField(max_length=1000, unique=True)
slug = models.SlugField(max_length=500, unique=True, blank=True)
seo_title = models.CharField(max_length=180, unique=True)
seo_description = models.TextField(max_length=280, unique=True)
class Meta:
verbose_name = 'category'
verbose_name_plural = 'categories'
def get_absolute_url(self):
return reverse('progress_category_url', kwargs={'slug': self.slug})
def save(self, *args, **kwargs):
if not self.id:
self.slug = generate_slug(self.name)
super().save(*args, **kwargs)
def __str__(self):
return self.name
class Progress(models.Model):
name = models.CharField(max_length=400, unique=True)
description = models.TextField(max_length=1000, unique=True)
slug = models.SlugField(max_length=500, unique=True, blank=True)
seo_title = models.CharField(max_length=180, unique=True)
seo_description = models.TextField(max_length=280, unique=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag)
date = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=False)
is_verified = models.BooleanField(default=False)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, blank=True, null=True)
promo_image = models.ImageField(upload_to='progress/promo_images/', null=True, blank=True)
class Meta:
verbose_name = 'progress'
verbose_name_plural = 'progresses'
def get_absolute_url(self):
return reverse('progress_url', kwargs={'slug': self.slug})
def save(self, *args, **kwargs):
if not self.id:
self.slug = generate_slug(self.name)
super().save(*args, **kwargs)
def __str__(self):
return self.name
Views
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from .models import Progress, Category
class ProgressView(DetailView):
model = Progress
template_name = 'progresses/detail_tpl.html'
class CategoryView(ListView):
model = Category
template_name = 'progresses/list_tpl.html'
URLs
from django.urls import path
from .views import ProgressView, CategoryView
urlpatterns = [
path('progress/<slug:slug>/', ProgressView.as_view(), name='progress_url'),
path('category/<slug:slug>/', CategoryView.as_view(), name='progress_category_url'),
]
So in my case I need to create something like that:
urlpatterns = [
path('<slug:category_slug>/<slug:progress_slug>/', ProgressView.as_view(), name='progress_url'),
]
How can I do this?