Django如何知道在urls.py中使用什么'pk'?

时间:2016-03-07 20:59:01

标签: python django

过去几周我一直在学习Django,有一件事似乎让我很困惑。 Django使用哪个模型的属性来定义<pk>中使用的urls.py

例如,如果我有:

urlpatterns = [
    url(r'^(?P<pk>\d+)/$', ProductDetailView.as_view(), name="product-detail"),
]

我之前假设pk将从给定视图中使用的模型实例派生,在本例中为ProductDetailView.as_view()。但是,我开始质疑这个逻辑,因为你可以将多个模型传递给视图。

第2部分

另外,如果我想使用一个模型实例的pk,而在视图中使用不同的模型实例,该怎么办?

例如,如果我有两个模型Products&amp; Stores两者都具有多对多关系(例如,产品可以在多个商店中,商店可以容纳许多产品)。然后我希望有一个url,其中StoreListView列出了包含给定产品的所有商店,所以我的网址会是这样的:

url(r'^(?P<pk>\d+)/$', StoreListView.as_view(), name="store-list")

pk属于Product个实例,而view属于Store个实例

再次确定问题,Django如何定义pk

3 个答案:

答案 0 :(得分:2)

Django没有定义任何东西。你定义它。 ProductDetailView 必须具有model属性;正是该属性定义了要使用的模型。

不幸的是,你问题的第2部分确实没有意义;视图不是模型的实例。

答案 1 :(得分:1)

在这里查看详细视图的各种方法和属性,尤其是get_object方法:

http://ccbv.co.uk/projects/Django/1.9/django.views.generic.detail/DetailView

def get_object(self, queryset=None):
    """
    Returns the object the view is displaying.
    By default this requires `self.queryset` and a `pk` or `slug` argument
    in the URLconf, but subclasses can override this to return any object.
    """
    # Use a custom queryset if provided; this is required for subclasses
    # like DateDetailView
    if queryset is None:
        queryset = self.get_queryset()
    # Next, try looking up by primary key.
    pk = self.kwargs.get(self.pk_url_kwarg)
    slug = self.kwargs.get(self.slug_url_kwarg)
    if pk is not None:
        queryset = queryset.filter(pk=pk)

    # Next, try looking up by slug.
    if slug is not None and (pk is None or self.query_pk_and_slug):
        slug_field = self.get_slug_field()
        queryset = queryset.filter(**{slug_field: slug})
    # If none of those are defined, it's an error.
    if pk is None and slug is None:
        raise AttributeError("Generic detail view %s must be called with "
                         "either an object pk or a slug."
                         % self.__class__.__name__)
    try:
        # Get the single item from the filtered queryset
        obj = queryset.get()
    except queryset.model.DoesNotExist:
        raise Http404(_("No %(verbose_name)s found matching the query") %
                  {'verbose_name': queryset.model._meta.verbose_name})

    return obj 

它是Django,因此它可以相当自定义,因此它不需要被称为“PK&#39;”。您可以使用pk_url_kwarg覆盖它。默认情况下,id字段是pk,除非您在模型定义中指定它。

答案 2 :(得分:0)

Django的DetailView使用SingleObjectMixin mixin,它有一个名为get_object的方法,它会查找pk_url_kwarg

 pk = self.kwargs.get(self.pk_url_kwarg)

默认设置为'pk'