强制url中的两个段塞都存在于datatabs中

2024-10-03 17:24:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我有多个类别和一些通过外键与这些类别相关的细节

例如,我有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')

但是正如在第一段代码中所写的,任何像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'),

Tags: pathnameselfviewlocalhostmodelsas类别
2条回答

您可以使用^{}path converter [Django-doc]

path('<slug:slug>', views.CategorieView.as_view(), name='categorie_name'),
path(
    '<slug:anythinghereworks>/<slug:slug>',
    views.DetailDetailView.as_view(),
    name='detail_name'
),

路径转换器封装指定可接受模式的正则表达式(例如int:路径转换器将只匹配一个数字序列),以及URL中的子字符串和对象之间的转换。这可以是字符串,例如在slug的情况下,但是int:路径转换器(例如)以int为目标

View中,可以重写get_queryset方法:

class DetailDetailView(DetailView):
    model = Detail
    slug_field = 'slug'
    template_name = "app/details.html"

    def get_queryset(self):
        return super(DetailView, self).get_queryset().filter(
            category__slug=self.request.kwargs['anythinghereworks']
        )

要正确过滤查询集。对于具有无效sluganythinghereworks的请求,这将引发404

(强烈)建议不要命名任何东西DetailView,因为它将覆盖模块中对新构造类的引用,因此文件后面的其他视图将继承自您的DetailView

然而,我建议寻找比anythinghereworks更好的命名法。例如,您可以将参数重命名为category_slugdetail_slug。这将避免很多混乱,从而避免(潜在的)错误

首先,将'anythinghereworks'重命名为更有用的名称,并重命名DetailView以避免与Django的DetailView冲突。例如:

path('<cat_slug>/<slug>', views.MyDetailView.as_view(), name='detail_name')

然后您可以覆盖get_object以在slugcat_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

相关问题 更多 >