Python Django通用视图:如何分配新属性?

Python Django通用视图:如何分配新属性?,python,django,class,django-generic-views,Python,Django,Class,Django Generic Views,我是Python新手,正在尝试了解Django 1.3基于类的泛型视图。现在,我有以下视图,它获取类别中位置对象的列表: class category_detail(ListView): """Return a generic view of locations in a category.""" def get_context_data(self, **kwargs): # Call the base implementation first to get a

我是Python新手,正在尝试了解Django 1.3基于类的泛型视图。现在,我有以下视图,它获取类别中位置对象的列表:

class category_detail(ListView):
    """Return a generic view of locations in a category."""

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context.
        context = super(category_detail, self).get_context_data(**kwargs)
        # Add the current category to the context.
        category = get_object_or_404(Category, slug=self.kwargs['slug'])
        context['category'] = category
        return context

    def get_queryset(self):
        category = get_object_or_404(Category, slug=self.kwargs['slug'])
        return Location.objects.filter(category=category)

它做了我想让它做的事。但是你可以看到我通过定义
category
两次来重复我自己。有没有一种方法可以将一个名为
category
的新属性添加到我在顶部定义过一次的类中,然后在
get\u queryset()
get\u context\u data()
中引用
self.category

@property
def category(self):
    return get_object_or_404(Category, slug=self.kwargs['slug'])

在类中,然后您可以作为
self.category
访问它,如果不使用装饰器,则可以使用
self.category()
使用
@属性
装饰器访问它

@property
def category(self):
    return get_object_or_404(Category, slug=self.kwargs['slug'])

在您的类中,然后您可以通过
self.category
访问它,而不使用decorator,则可以通过
self.category()访问它

我认为你应该从另一个角度来看待它:你不应该使用
列表视图
来显示
类别的
位置
,而是
类别的
详细视图
,其中也包括该类别的
位置
。视图类的名称还表明您正在显示类别的详细视图。我认为应该是这样的:

class CategoryLocationsView(DetailView):
    model = Category
    context_object_name = 'category'

    def get_context_data(self, **kwargs):
        context = super(CategoryLocationsView, self).get_context_data(**kwargs)
        context['location_list'] = self.get_object().location_set.all()
        return context

现在,您可以在模板中使用上下文中的类别和位置列表。

我认为您应该从不同的角度来处理它:您不应该使用
列表视图
显示
类别
位置
,而应该使用
类别
详细视图
包括该类别的
位置
。视图类的名称还表明您正在显示类别的详细视图。我认为应该是这样的:

class CategoryLocationsView(DetailView):
    model = Category
    context_object_name = 'category'

    def get_context_data(self, **kwargs):
        context = super(CategoryLocationsView, self).get_context_data(**kwargs)
        context['location_list'] = self.get_object().location_set.all()
        return context

现在,您的上下文中既有类别,也有位置列表,可以在模板中使用。

只需将类别分配给
self
。唯一需要注意的是,您需要对在何处执行该操作稍微小心一点,因为有些方法是在其他方法之前调用的。但是,
get\u queryset
是视图中首先激活的内容之一,因此它在那里可以正常工作:

def get_queryset(self):
    self.category = get_object_or_404(Category, slug=self.kwargs['slug'])
    return Location.objects.filter(category=self.category)

def get_context_data(self, **kwargs):
    # Call the base implementation first to get a context.
    context = super(category_detail, self).get_context_data(**kwargs)
    # Add the current category to the context.
    context['category'] = self.category
    return context

FWIW,这实际上是(第三个代码示例向下)使用的确切方法。

只需将类别分配给
self
。唯一需要注意的是,您需要对在何处执行该操作稍微小心一点,因为有些方法是在其他方法之前调用的。但是,
get\u queryset
是视图中首先激活的内容之一,因此它在那里可以正常工作:

def get_queryset(self):
    self.category = get_object_or_404(Category, slug=self.kwargs['slug'])
    return Location.objects.filter(category=self.category)

def get_context_data(self, **kwargs):
    # Call the base implementation first to get a context.
    context = super(category_detail, self).get_context_data(**kwargs)
    # Add the current category to the context.
    context['category'] = self.category
    return context

FWIW,这实际上是(第三个代码示例向下)使用的确切方法。

+1。此外,您还可以通过完全删除
get\u context\u data
方法进一步简化代码,并将
{%with location\u list=category.location\u set.all%}
放在模板中。这比我尝试做的更有意义。谢谢+1.此外,您还可以通过完全删除
get\u context\u data
方法进一步简化代码,并将
{%with location\u list=category.location\u set.all%}
放在模板中。这比我尝试做的更有意义。谢谢