在Django中重用相同的URL模式

时间:2016-11-14 23:37:23

标签: django django-urls django-class-based-views

我正在建立一个简单的网上商店。有Category个对象和Product个对象。

我希望两者的网址都位于顶层,即Category名为" Jacket"将在http://example.com/jacketProduct命名为" Foo"将在http://example.com/foo

我不确定如何在我的网址中处理此问题,因为两者都匹配相同的正则表达式。我可以只有一个DetailView覆盖get_object(),首先检查带有slug的产品,然后检查一个带有slug的类别并返回它先找到的那个。 (如果产品和产品都具有相同的slug,我想要提供产品。)

有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:0)

处理此问题的唯一更好方法是遵循最佳做法并在网址中命名对象,即http://example.com/products/foohttp://example.com/categories/jacket

如果你绝对需要一切都在根级别域(这是一个不常见的需求,使得在根级别添加任何新路由更加困难,并且如你在问题中提到的那样让位于ID冲突)我会建议仍然像我上面那样设置你的URL,并编写第三个视图,它在根级别捕获r'^(?P<vanity>.+)/',并且可能在正确的URL上执行302。像这样:

class CatchAllView(View):
    def get(self, request, *args, **kwargs):
        vanity = kwargs.get('vanity')

        if Products.objects.filter(pk=vanity):
            return redirect('product', vanity=vanity)
        elif Categories.objects.filter(pk=vanity):
            return redirect('category', vanity=vanity)
        else:
            raise Http404("No such category or product.")

至少在这种情况下,如果发生碰撞,您实际上会有一个URL来获取每个产品和类别。