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?
Related
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']
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'),
class Article(models.Model):
Title = models.CharField(max_length = 255)
writing = models.TextField()
category = models.CharField(max_length = 225)
published = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
slug = models.SlugField(blank=True, editable=False)
def save(self):
self.slug = slugify(self.Title)
super().save()
def get_absolute_url(self):
url_slug = {'slug':self.slug}
return reverse('artikel:ArticleDetail', kwargs = url_slug)
def __str__(self):
return "{}.{}".format(self.id, self.Title)
i want to build a simple website using django where it could post some articles by form. The problem is how could i post multiple category in one article ? this is form.py below.
from .models import Article
from django.forms import ModelForm
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = [
'title',
'writing',
'category',
]
You can a ManyToManyField to link your post to multiple categories, for example:
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=255)
writing = models.TextField()
category = models.ManyToManyField(Category)
published = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
slug = models.SlugField(blank=True, editable=False)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save()
def get_absolute_url(self):
return reverse('artikel:ArticleDetail', kwargs={'slug': self.slug})
def __str__(self):
return '{}.{}'.format(self.id, self.title)
That being said, there already are some packages for this. django-taggit [GitHub] for example, you can install this with:
pip3 install django-taggit
and include 'taggit' to the INSTALLED_APPS list [Django-doc]:
# settings.py
INSTALLED_APPS = [
# …,
'taggit',
# …
]
Then in your models, you can add a TaggableManager to the model:
from django.db import models
from taggit.managers import TaggableManager
class Article(models.Model):
title = models.CharField(max_length=255)
writing = models.TextField()
categories = TaggableManager()
published = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
slug = models.SlugField(blank=True, editable=False)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save()
def get_absolute_url(self):
return reverse('artikel:ArticleDetail', kwargs={'slug': self.slug})
def __str__(self):
return '{}.{}'.format(self.id, self.title)
As the documentation specifies, it comes with a form field that allows one to write space-separated and comma-separated tags.
I have a little problem with display subcategories belongs only in specific categories. For example: I have a categories: Business, Factory, Health ... and after I can add subcategories for example Own Company in category Business. In this case if I choose category Business I need to have only visible subcategories belongs to this category. How to make it?
This is my code.
models.py
from django.db import models
from slugify import slugify
class Kategoria(models.Model):
name = models.CharField(max_length=50, unique=True, verbose_name='Nazwa kategorii')
slug = models.SlugField(verbose_name='Adres SEO')
class Meta:
verbose_name_plural = 'Kategorie'
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Kategoria, self).save(*args, **kwargs)
def __str__(self):
return self.name
class Subkategoria(models.Model):
category = models.ForeignKey('Kategoria', related_name='subkategoria', on_delete=models.CASCADE, blank=True, null=True, verbose_name='Kategoria główna')
name = models.CharField(max_length=50)
class Meta:
verbose_name_plural = 'Subkategorie'
def __str__(self):
return self.name
class Strona(models.Model):
name = models.CharField(max_length=250, verbose_name='Nazwa strony')
slug = models.SlugField(verbose_name='Adres SEO')
www = models.CharField(max_length=200, verbose_name='Adres strony', unique=True)
content = models.TextField(verbose_name='Opis')
category = models.ForeignKey('Kategoria', verbose_name='Kategoria', on_delete=models.CASCADE)
subcategory = models.ForeignKey('Subkategoria', verbose_name='Subkategoria', on_delete=models.CASCADE)
publish = models.DateField(auto_now=False, auto_now_add=False)
class Meta:
verbose_name_plural = 'Strony'
def __str__(self):
return self.name
trying to do the Django Rest Framework foreign key serialization ,,however I got this error,
models.py
class ProductsTbl(models.Model):
model_number = models.CharField(
max_length=255,
blank=True,
unique=True,
error_messages={
'unique': "這 model number 已經被註冊了 ."
}
)
name = models.CharField(max_length=255, blank=True, null=True)
material = models.CharField(max_length=255, blank=True, null=True)
color = models.CharField(max_length=255, blank=True, null=True)
feature = models.TextField(blank=True, null=True)
created = models.DateTimeField(editable=False)
modified = models.DateTimeField(auto_now=True)
release = models.DateTimeField(blank=True, null=True)
twtime = models.DateTimeField(blank=True, null=True)
hktime = models.DateTimeField(blank=True, null=True)
shtime = models.DateTimeField(blank=True, null=True)
jptime = models.DateTimeField(blank=True, null=True)
suggest = models.TextField(blank=True, null=True)
description = models.TextField(blank=True, null=True)
user = models.ForeignKey(User, blank=True, null=True)
useredit = models.CharField(max_length=32, blank=True, null=True)
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.id:
self.created = timezone.now()
return super(ProductsTbl, self).save(*args, **kwargs)
def get_image_path(instance, filename):
return '/'.join(['thing_images', instance.thing.slug, filename])
class Upload(models.Model):
thing = models.ForeignKey(ProductsTbl, related_name="uploads")
image = models.ImageField(upload_to=get_image_path, verbose_name='Image')
def save(self, *args, **kwargs):
super(Upload, self).save(*args, **kwargs)
if self.image:
image = Image.open(self.image)
i_width, i_height = image.size
max_size = (640, 480)
if i_width > 1000:
image.thumbnail(max_size, Image.ANTIALIAS)
image.save(self.image.path)
api/serializers.py
from rest_framework import serializers
from ..models import *
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
UserModel = get_user_model()
class UploadSerializers(serializers.ModelSerializer):
class Meta:
model = Upload
fields = ('image',)
class ProductsTblSerializer(serializers.HyperlinkedModelSerializer):
uploads = UploadSerializers.HyperlinkedModelSerializer(many=True,read_only=True)
class Meta:
model = ProductsTbl
fields = ('model_number',
'created',
'name',
'release',
'twtime',
'hktime',
'shtime',
'jptime',
'feature',
'material',
'suggest',
'description',
'cataloggroup',
'place',
'scale',
'slug',
'user',
'uploads')
api/urls.py
from django.conf.urls import url, include
from . import views
urlpatterns = [
url(r'^productsTbls/$', views.ProductsTblListView.as_view(), name='productsTbls_list'),
url(r'^productsTbls/(?P<pk>\d+)/$', views.ProductsTblDetailView.as_view(), name='productsTbls_detail'),
url(r'^productsTbls/pdelete/(?P<id>[-\w]+)/$',views.api_delete_product,name='api_delete_p'),
url(r'^productsTbls/register/$', views.CreateUserView.as_view(), name='productsTbls_register'),
]
api/views.py
from rest_framework.parsers import JSONParser
from django.views.decorators.csrf import csrf_exempt
from django.forms import modelformset_factory
from django.template.defaultfilters import slugify
from rest_framework import permissions
from rest_framework.generics import CreateAPIView
from django.contrib.auth import get_user_model
from rest_framework.permissions import AllowAny
class ProductsTblListView(generics.ListCreateAPIView):
queryset = ProductsTbl.objects.order_by('-created')
serializer_class = ProductsTblSerializer
class ProductsTblDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = ProductsTbl.objects.all()
serializer_class = ProductsTblSerializer
however ,,if I changed the api/serializers.py like below
......
class ProductsTblSerializer(serializers.ModelSerializer):
uploads = UploadSerializers(many=True,read_only=True)
......
I can see http://127.0.0.1:8000/api/productsTbls/ my page come out,,but without the image link,how can I show the image link in "uploads":[]? thank you (django rest framework 3.4)
You've inherited your UploadSerializer class from serializers.ModelSerializer, not from serializers.HyperLinkedModelSerializer
class UploadSerializers(serializers.ModelSerializer):
class Meta:
model = Upload
fields = ('image',)
So when you try to use it as
uploads = UploadSerializers.HyperlinkedModelSerializer(many=True,read_only=True)
it doesn't have that attribute.
If you make your initial declaration of UploadSerializers inherit from the hyperlink class, it should work.
class UploadSerializers(serializers.HyperlinkedModelSerializer):
class Meta:
model = Upload
fields = ('image',)
Then you should be able to use:
uploads = UploadSerializers(many=True,read_only=True)