强制 url 中的两个 slug 存在于数据库中
force both slugs in url to exist in datatabse
我有多个类别和一些通过外键与这些类别相关的详细信息。
例如,我有 categorie1 和 detail1。
现在我可以在 url localhost:8000/categorie1
中调用类别
path('<slug>', views.CategorieView.as_view(), name='categorie_name')
及详情:localhost:8000/categorie1/detail1
path('<anythinghereworks>/<slug>', views.DetailView.as_view(), name='detail_name')
但是正如第一个 slug 中所写,任何 localhost:8000/abc/details1 之类的 URL 都可以。
如何制作 2 只蛞蝓的图案?
#Model
class Categorie(models.Model):
name = models.CharField(max_length=50,unique=True)
slug = models.SlugField(max_length=100,unique=True)
def __str__(self):
return self.name
class Detail(models.Model):
title = models.CharField(max_length=100)
slug= models.SlugField(max_length=100,unique=True)
categorie = models.ForeignKey('Categorie', on_delete=models.CASCADE, related_name="details")
def __str__(self):
return self.title
#Views
class CategorieView(DetailView):
model = Categorie
slug_field = 'slug'
template_name = "app/categories.html"
class DetailView(DetailView):
model = Detail
slug_field = 'slug'
template_name = "app/details.html"
#URLs
path('<slug>', views.CategorieView.as_view(), name='categorie_name'),
path('<anythinghereworks>/<slug>', views.DetailView.as_view(), name='detail_name'),
您使用 slug:
path converter [Django-doc]:
path('<<b>slug:</b>slug>', views.CategorieView.as_view(), name='categorie_name'),
path(
'<<b>slug:</b>anythinghereworks>/<<b>slug:</b>slug>',
views.<b>Detail</b>DetailView.as_view(),
name='detail_name'
),
路径转换器封装了指定可接受模式的正则表达式(例如 int:
路径转换器将仅匹配数字序列),以及 URL 中的子字符串之间的转换和一个对象。这可以是一个字符串,例如 slug
,但 int:
路径转换器的目标是 int
.
在您的 View
中,您可以覆盖 get_queryset
方法:
class <b>Detail</b>DetailView(DetailView):
model = Detail
slug_field = 'slug'
template_name = "app/details.html"
def <b>get_queryset</b>(self):
return super(DetailView, self).get_queryset().filter(
category__slug=self.request.kwargs['anythinghereworks']
)
正确过滤查询集。对于具有无效 slug
或 anythinghereworks
的请求,这将引发 404.
还(强烈)建议不要命名任何内容DetailView
,因为它会覆盖您的引用模块到新构建的 class,因此文件后面的其他视图将继承自 your DetailView
.
不过,我建议寻找比 anythinghereworks
更好的命名法。例如,您可以将参数重命名为 category_slug
和 detail_slug
。这将避免很多混乱,从而避免(潜在的)错误。
首先,将 'anythinghereworks'
重命名为更有用的名称,并重命名 DetailView
以避免与 Django 的 DetailView
冲突。例如:
path('<cat_slug>/<slug>', views.MyDetailView.as_view(), name='detail_name')
然后您可以覆盖 get_object
以过滤 slug
和 cat_slug
。
class MyDetailView(DetailView):
def get_object(self):
return Detail.objects.get(slug=self.kwargs['slug'], categorie__slug='self.kwargs['cat_slug'])
或者您可以覆盖 get_queryset
并在那里过滤类别。你不需要在这里过滤 slug=self.kwargs['slug']
因为 Django 会在 get_object
方法中处理它。
class MyDetailView(DetailView):
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(categorie__slug=self.kwargs['cat_slug'])
return queryset
在这两种情况下您都可以删除 slug_field = 'slug'
,因为 'slug'
是默认值。在第一种情况下,Django 将使用您的 get_object
方法,因此根本不会使用 slug_field
。
我有多个类别和一些通过外键与这些类别相关的详细信息。
例如,我有 categorie1 和 detail1。
现在我可以在 url localhost:8000/categorie1
中调用类别 path('<slug>', views.CategorieView.as_view(), name='categorie_name')
及详情:localhost:8000/categorie1/detail1
path('<anythinghereworks>/<slug>', views.DetailView.as_view(), name='detail_name')
但是正如第一个 slug 中所写,任何 localhost:8000/abc/details1 之类的 URL 都可以。
如何制作 2 只蛞蝓的图案?
#Model
class Categorie(models.Model):
name = models.CharField(max_length=50,unique=True)
slug = models.SlugField(max_length=100,unique=True)
def __str__(self):
return self.name
class Detail(models.Model):
title = models.CharField(max_length=100)
slug= models.SlugField(max_length=100,unique=True)
categorie = models.ForeignKey('Categorie', on_delete=models.CASCADE, related_name="details")
def __str__(self):
return self.title
#Views
class CategorieView(DetailView):
model = Categorie
slug_field = 'slug'
template_name = "app/categories.html"
class DetailView(DetailView):
model = Detail
slug_field = 'slug'
template_name = "app/details.html"
#URLs
path('<slug>', views.CategorieView.as_view(), name='categorie_name'),
path('<anythinghereworks>/<slug>', views.DetailView.as_view(), name='detail_name'),
您使用 slug:
path converter [Django-doc]:
path('<<b>slug:</b>slug>', views.CategorieView.as_view(), name='categorie_name'),
path(
'<<b>slug:</b>anythinghereworks>/<<b>slug:</b>slug>',
views.<b>Detail</b>DetailView.as_view(),
name='detail_name'
),
路径转换器封装了指定可接受模式的正则表达式(例如 int:
路径转换器将仅匹配数字序列),以及 URL 中的子字符串之间的转换和一个对象。这可以是一个字符串,例如 slug
,但 int:
路径转换器的目标是 int
.
在您的 View
中,您可以覆盖 get_queryset
方法:
class <b>Detail</b>DetailView(DetailView):
model = Detail
slug_field = 'slug'
template_name = "app/details.html"
def <b>get_queryset</b>(self):
return super(DetailView, self).get_queryset().filter(
category__slug=self.request.kwargs['anythinghereworks']
)
正确过滤查询集。对于具有无效 slug
或 anythinghereworks
的请求,这将引发 404.
还(强烈)建议不要命名任何内容DetailView
,因为它会覆盖您的引用模块到新构建的 class,因此文件后面的其他视图将继承自 your DetailView
.
不过,我建议寻找比 anythinghereworks
更好的命名法。例如,您可以将参数重命名为 category_slug
和 detail_slug
。这将避免很多混乱,从而避免(潜在的)错误。
首先,将 'anythinghereworks'
重命名为更有用的名称,并重命名 DetailView
以避免与 Django 的 DetailView
冲突。例如:
path('<cat_slug>/<slug>', views.MyDetailView.as_view(), name='detail_name')
然后您可以覆盖 get_object
以过滤 slug
和 cat_slug
。
class MyDetailView(DetailView):
def get_object(self):
return Detail.objects.get(slug=self.kwargs['slug'], categorie__slug='self.kwargs['cat_slug'])
或者您可以覆盖 get_queryset
并在那里过滤类别。你不需要在这里过滤 slug=self.kwargs['slug']
因为 Django 会在 get_object
方法中处理它。
class MyDetailView(DetailView):
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(categorie__slug=self.kwargs['cat_slug'])
return queryset
在这两种情况下您都可以删除 slug_field = 'slug'
,因为 'slug'
是默认值。在第一种情况下,Django 将使用您的 get_object
方法,因此根本不会使用 slug_field
。