Django Generic Views: Как назначить новое свойство? - PullRequest
0 голосов
/ 16 марта 2012

Я новичок в Python и пытаюсь понять общие представления Django 1.3 на основе классов.Прямо сейчас у меня есть следующий вид, который получает список объектов Location в категории:

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, который я определяю один раз в верхней части, а затем просто ссылаться на self.category в get_queryset() и get_context_data()?

Ответы [ 3 ]

3 голосов
/ 16 марта 2012

Я думаю, вы должны подходить к нему под другим углом: вы не должны использовать ListView, показывающий Locations из Category, а DetailView из Category, который также включает Locations эта категория. Название вашего класса представления также предполагает, что вы показываете подробный вид категории. Я думаю, это должно выглядеть примерно так:

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

Теперь у вас есть категория и список местоположений в вашем контексте, которые вы можете использовать в шаблоне.

2 голосов
/ 16 марта 2012

Просто назначьте категорию для self.Единственное предостережение в том, что вам нужно быть немного осторожнее с тем, где вы это делаете, потому что некоторые методы вызываются раньше других.Тем не менее, get_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, это именно тот метод, который используется в документах Djangoоснованные на классе представления (третий пример кода вниз).

1 голос
/ 16 марта 2012

используйте @property декоратор

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

внутри вашего класса, и тогда вы сможете получить к нему доступ как self.category, без декоратора он будет доступен с self.category()

...