2015-10-23 2 views
0

Так скажем, у меня есть модель под названием Card:Джанго Лучший способ использовать View как ListView

models.py

class Card(models.Model): 
    user = models.ForeignKey(User) 
    title = models.CharField(max_length=10, blank=True) 

и теперь давайте скажем я вид:

просмотры. ру

class CardView(View): 
    def get(self, request, *args, **kwargs): 
     cards = Card.objects.filter(user=request.user) 
     return render(request, 'index.html', {'cards': cards}) 

Мой вопрос заключается в следующем: Как я могу реорганизовать CardView так что я могу абстрагировать фильтрацию Карт в Суперкласс, который можно унаследовать? В ListView я знаю, что могу просто создать еще один класс, который наследует от object, переопределить get_context_data, а затем называть его так: class CardListView(CardObjectsMixin, ListView), но можно ли сделать то же самое с общим классом View?

ответ

0

Уверенный, вы можете. Вы можете создать класс следующим образом:

class CardsCustomView(View): 
    ... 

class CardView(CardsCustomView): 

    def get(self, request, *args, **kwargs): 
     ... 

Поскольку CardView простирается от CardCustomView и это один простирается от View. В CardView вы можете получить доступ к любому атрибуту или методу View (listed here) и любому атрибуту или методу, который вы создаете в CardCustomView. Давайте возьмем пример:

class CardCustomView(View): 

    state = 'started' # just an example 

    def get_user_cards(self): 
     return Card.objects.filter(user=self.request.user) 

Тогда вы можете:

class CardView(CardCustomView): 

    def get(self, request, *args, **kwargs): 
     self.state ... # This has 'started' value from parent class. 
     self.current_user_cards = self.get_user_cards() # This should have the cards for the current user 

О вашем комментарии, базовый класс View не имеет метод .get_context_data(), как вы можете видеть в ссылке, которую я Приведенная выше.

+0

Я должен быть более понятным - после того, что вы опубликовали, существует способ слияния контекстов из унаследованного 'get()' с подклассовым 'get()'? – Hybrid

+0

@Hybrid Я отредактировал ответ. – Gocht

+0

Хорошо, но вы видите, что проблема заключается в том, что я фильтрую «Пользователь», поэтому невозможно добавить эквивалент ('state') в качестве поля класса (так как' request.user' не существует на уровне класса). – Hybrid

0

ListViews уже содержит эту функцию. Все, что вам нужно сделать, это переопределить get_queryset, чтобы вернуть qs, отфильтрованный пользователем; все ваши взгляды могут затем наследовать это.

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

class MyBaseView(object): 
    def get_queryset(self): 
     return super(MyBaseView, self).get_queryset().filter(user=self.request.user) 
Смежные вопросы