django 子类别 slug 过滤器
django subcategory slug filter
了解 Django 并跟随 tango with Django 这本书,但是最后一期是在添加子类别之后让我明白的,这些子类别未包含在该教程中。
我有以下内容:
models.py
class Category(models.Model):
"""Category"""
name = models.CharField(max_length=50)
slug = models.SlugField()
def save(self, *args, **kwargs):
#self.slug = slugify(self.name)
self.slug = slugify(self.name)
super(Category, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
class SubCategory(models.Model):
"""Sub Category"""
category = models.ForeignKey(Category)
name = models.CharField(max_length=50)
slug = models.SlugField()
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(SubCategory, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
和
urls.py
(r'^links/$', 'rango.views.links'),
(r'^links/(?P<category_name_slug>[\w\-]+)/$', 'rango.views.category'),
(r'^links/(?P<category_name_slug>[\w\-]+)/(?P<subcategory_name_slug>[\w\-]+)/$', 'rango.views.subcategory'),
和
views.py
@require_GET
def links(request):
"""Linkdirectory Page"""
category_list = Category.objects.order_by('name')
context_dict = {'categories': category_list}
return render(request, 'links.html', context_dict)
@require_GET
def category(request, category_name_slug):
"""Category Page"""
category = Category.objects.get(slug=category_name_slug)
subcategory_list = SubCategory.objects.filter(category=category)
context_dict = {'subcategories': subcategory_list}
return render(request, 'category.html', context_dict)
@require_GET
def subcategory(request, subcategory_name_slug, category_name_slug):
"""SubCategory Page"""
context_dict = {}
try:
subcategory = SubCategory.objects.get(slug=subcategory_name_slug)
context_dict['subcategory_name'] = subcategory.name
websites = Website.objects.filter(sub_categories=subcategory)
context_dict['websites'] = websites
context_dict['subcategory'] = subcategory
except SubCategory.DoesNotExist:
return render(request, 'subcategory.html', context_dict)
在我添加具有相同名称的子类别之前,这一切都很好,例如多个类别的子类别 "other"。
我明白为什么,当我达到 "def subcategory" 时,我的 slug 会 return 多个子类别,所以我需要以某种方式将它们限制在相关类别中,比如
"SELECT
subcategory = SubCategory.objects.get(slug=subcategory_name_slug)
WHERE
subcategory = SubCategory.objects.filter(category=subcategory)
CLAUSE"
之类的 ;)
不确定处理此问题的最佳途径是什么以及如何过滤这些
鉴于您可能有两个不同的 SubCategory
对象,两个不同的 Category
对象具有相同的名称,正如您所建议的那样,您可以添加 Category
作为附加过滤器。
同时按 SubCategory.slug 和 Category.slug
过滤
为了实现这一点,我看到您有一个视图,它对 SubCategory
和 Category
都采用 slug,您这样定义的 subcategory(request, subcategory_name_slug, category_name_slug)
。这些足以过滤:
subcategory = SubCategory.objects.get(
slug=subcategory_name_slug,
category__slug=category_name_slug
)
^
|__ # This "double" underscore category__slug is a way to filter
# a related object (SubCategory.category)
# So effectively it's like filtering for SubCategory objects where
# SubCategory.category.slug is category_name_slug
你看到上面我使用 SubCateogry.objects.get(...)
来获取单个对象而不是 `SubCategory.objects.filter(...) 可以 return 许多对象。
每个类别 SubCategory.name 的 单一性
要使用 get()
安全地执行此操作,需要保证对于任何给定类别,不超过一个 个具有相同名称的子类别
您可以使用 unique_together
强制执行此条件
class SubCategory(models.Model):
class Meta:
unique_together = (
('category', 'name'), # since slug is based on name,
# we are sure slug will be unique too
)
了解 Django 并跟随 tango with Django 这本书,但是最后一期是在添加子类别之后让我明白的,这些子类别未包含在该教程中。
我有以下内容:
models.py
class Category(models.Model):
"""Category"""
name = models.CharField(max_length=50)
slug = models.SlugField()
def save(self, *args, **kwargs):
#self.slug = slugify(self.name)
self.slug = slugify(self.name)
super(Category, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
class SubCategory(models.Model):
"""Sub Category"""
category = models.ForeignKey(Category)
name = models.CharField(max_length=50)
slug = models.SlugField()
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(SubCategory, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
和
urls.py
(r'^links/$', 'rango.views.links'),
(r'^links/(?P<category_name_slug>[\w\-]+)/$', 'rango.views.category'),
(r'^links/(?P<category_name_slug>[\w\-]+)/(?P<subcategory_name_slug>[\w\-]+)/$', 'rango.views.subcategory'),
和
views.py
@require_GET
def links(request):
"""Linkdirectory Page"""
category_list = Category.objects.order_by('name')
context_dict = {'categories': category_list}
return render(request, 'links.html', context_dict)
@require_GET
def category(request, category_name_slug):
"""Category Page"""
category = Category.objects.get(slug=category_name_slug)
subcategory_list = SubCategory.objects.filter(category=category)
context_dict = {'subcategories': subcategory_list}
return render(request, 'category.html', context_dict)
@require_GET
def subcategory(request, subcategory_name_slug, category_name_slug):
"""SubCategory Page"""
context_dict = {}
try:
subcategory = SubCategory.objects.get(slug=subcategory_name_slug)
context_dict['subcategory_name'] = subcategory.name
websites = Website.objects.filter(sub_categories=subcategory)
context_dict['websites'] = websites
context_dict['subcategory'] = subcategory
except SubCategory.DoesNotExist:
return render(request, 'subcategory.html', context_dict)
在我添加具有相同名称的子类别之前,这一切都很好,例如多个类别的子类别 "other"。
我明白为什么,当我达到 "def subcategory" 时,我的 slug 会 return 多个子类别,所以我需要以某种方式将它们限制在相关类别中,比如
"SELECT
subcategory = SubCategory.objects.get(slug=subcategory_name_slug)
WHERE
subcategory = SubCategory.objects.filter(category=subcategory)
CLAUSE"
之类的 ;)
不确定处理此问题的最佳途径是什么以及如何过滤这些
鉴于您可能有两个不同的 SubCategory
对象,两个不同的 Category
对象具有相同的名称,正如您所建议的那样,您可以添加 Category
作为附加过滤器。
同时按 SubCategory.slug 和 Category.slug
过滤为了实现这一点,我看到您有一个视图,它对 SubCategory
和 Category
都采用 slug,您这样定义的 subcategory(request, subcategory_name_slug, category_name_slug)
。这些足以过滤:
subcategory = SubCategory.objects.get(
slug=subcategory_name_slug,
category__slug=category_name_slug
)
^
|__ # This "double" underscore category__slug is a way to filter
# a related object (SubCategory.category)
# So effectively it's like filtering for SubCategory objects where
# SubCategory.category.slug is category_name_slug
你看到上面我使用 SubCateogry.objects.get(...)
来获取单个对象而不是 `SubCategory.objects.filter(...) 可以 return 许多对象。
每个类别 SubCategory.name 的 单一性
要使用 get()
安全地执行此操作,需要保证对于任何给定类别,不超过一个 个具有相同名称的子类别
您可以使用 unique_together
class SubCategory(models.Model):
class Meta:
unique_together = (
('category', 'name'), # since slug is based on name,
# we are sure slug will be unique too
)