Общие виды Django: когда использовать ListView против DetailView
Я использую основанные на классах общие представления Django в приложении блога. Один из моих просмотров отображает список сообщений, которые имеют определенный тег. Я могу написать эту точку зрения как ListView
сообщений, отфильтрованных по тегу. Или я могу написать эту точку зрения как DetailView
тега и добавьте соответствующие сообщения в контекст.
Один способ более правильный - или Pythonic - чем другой?
ListView
подход кажется более семантическим, потому что мне нужен список постов, но он также немного сложнее. Это требует, чтобы я переписал два метода. DetailView
Подход требует только от меня перезаписать один метод.
class PostTagView(ListView):
"""Display all blog posts with a given tag."""
queryset = Post.objects.published()
def get_context_data(self, **kwargs):
context = super(PostTagView, self).get_context_data(**kwargs)
context['tag'] = get_object_or_404(Tag, slug=self.kwargs['slug'])
return context
def get_queryset(self, **kwargs):
queryset = super(PostTagView, self).get_queryset()
return queryset.filter(tags__slug=self.kwargs['slug'])
class TagDetailView(DetailView):
"""Display all blog posts with a given tag."""
model = Tag
def get_context_data(self, **kwargs):
context = super(TagDetailView, self).get_context_data(**kwargs)
context['object_list'] = Post.objects.published().filter(tags__slug=self.kwargs['slug'])
return context
3 ответа
Как правило, посмотрите на параметры в URL. Если вы используете slug
из Tag
то вы, скорее всего, имеете дело с DetailView
и не ListView
,
В этом случае второй подход использует меньше кода, и он более элегантен. Однако это также зависит от того, что вы собираетесь делать с представлением позже. Если вы собираетесь добавить формы для редактирования сообщений, возможно, имеет смысл использовать ListView
вместо. Но нет никакой технической причины, чтобы отдавать предпочтение одному над другим, просто вы можете в конечном итоге написать больше кода в одном подходе, чем в другом.
И ListView, и DetailView не являются технически одинаковыми. Например, вы не можете указать путь для DetailView, как показано ниже в urls.py,
path('schools_detail/',views.SchoolDetailView.as_view(),name = "detail"),
Это даст ошибку ниже,
Общий подробный вид SchoolDetailView должен вызываться с объектом pk или слагом в URLconf.
Это означает, что если у нас есть таблица с именем Student и другая таблица с именем School, мы можем использовать ListView для перечисления всех школ, как показано ниже,
path('list/',views.SchoolListView.as_view(),name = "list"),
И если мы хотим перечислить сведения о школах для отдельной школы, когда мы нажимаем значок школы, то мы можем использовать первичный ключ школы, который Django создает внутри, и записывать его в шаблон URL, в моем случае шаблон URL будет "list/{{school.id}}"поэтому, чтобы захватить это, мы должны дать путь, как показано ниже для DetailsView,
path('list/<int:pk>/',views.SchoolDetailView.as_view(),name = "detail"),
Таким образом, в итоге вы можете использовать ListView в качестве обычного представления для большинства случаев, если вы хотите получить доступ к другому представлению, но только к определенной детали в этом представлении, которое ссылается на первичный ключ, тогда вы можете использовать DetailsView (шаблон URL для DetailsView будет сгенерирован путем предоставления информации первичного ключа в URL, без первичного ключа в URL, он не будет работать, поскольку он не будет принимать всю информацию, вместо этого он будет принимать только информацию, относящуюся к первичному ключу в URL).
Интересный вопрос. К сожалению, ответ не так интересен: какой из них имеет наибольшее значение для вас и вашего приложения. Аргументы могут быть сделаны одинаково для любого подхода, так что на самом деле это просто суждение.
Вариант использования универсальных представлений на основе классов прекрасно описан в статье:
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views
В вышеупомянутой статье вы сможете узнать, когда, почему и как использовать ListView/DetailView, а также простые примеры.