Переопределить get() в Django Class Based View для фильтра

Вопрос: Я начинаю новое приложение, и я изо всех сил стараюсь использовать классные представления. Ahhh, растущие боли. Я пытаюсь сделать простой фильтр здесь из GET-переменной, если он не существует. Я хочу вернуть все объекты, упорядоченные по id desc, если это так, я хочу фильтровать, упорядочивать и возвращать отфильтрованный список. Я пишу 30+ строки кода, чтобы

Вопрос:

Я начинаю новое приложение, и я изо всех сил стараюсь использовать классные представления. Ahhh, растущие боли. Я пытаюсь сделать простой фильтр здесь из GET-переменной, если он не существует. Я хочу вернуть все объекты, упорядоченные по id desc, если это так, я хочу фильтровать, упорядочивать и возвращать отфильтрованный список.

Я пишу 30+ строки кода, чтобы сделать это, поэтому я должен делать что-то неправильно, не так ли? Я попытался переопределить get_queryset(), и теперь, когда я думаю об этом, возможно, мне нужно вызвать self.request.GET [‘search’] в get_queryset(), чтобы сделать эту фильтрацию. Есть ли стандартный способ достижения этого?

class MyModelList(AdminPageMixin, ListView): model = MyModel context_object_name = ‘object’ template_name = ‘template/list.html’ def get(self, request, *args, **kwargs): if ‘search’ in request.GET and len(request.GET[‘search’]): search = request.GET[‘search’] self.object_list = MyModel.objects.filter(advertiser__name=search).orderby(‘-id’) context = self.get_context_data(object_list=self.object_list, search=search) else: self.object_list = MyModel.objects.all() context = self.get_context_data(object_list=self.object_list).orderby(‘-id’) return self.render_to_response(context) def get_context_data(self, **kwargs): context = super(MyModelList, self).get_context_data(**kwargs) form = MyModelForm try: context[‘search’] = kwargs[‘search’] except KeyError: pass context[‘form’] = form context[‘form_action’] = reverse(‘mymodel-add’) context[‘form_display’] = ‘hide’ context[‘form_save_label’] = ‘Add’ return context

Во-вторых, чтобы усложнить дело, у меня есть CreateView и UpdateView, которые я бы хотел поделиться с методами get() или get_queryset() и get_context_data() моего ListView. Я уверен, что это возможно с помощью Mixin, но опять же, я ищу стандартизированный способ сделать это. Предложения? Вот CreateView, в котором я хотел бы поделиться методами ListView.

class MyModelAdd(AdminPageMixin, CreateView): model = MyModel form_class = MyModelForm context_object_name = ‘object’ template_name = ‘templates/list.html’ def get_success_url(self): return reverse(‘mymodel-list’) def get_context_data(self, **kwargs): context = super(MyModelAdd, self).get_context_data(**kwargs) context[‘form_action’] = reverse(‘mymodel-add’) context[‘form_display’] = ‘show’ context[‘object_list’] = MyModel.objects.all() return context def form_invalid(self, form): form = MyModelForm(self.request.POST) context = self.get_context_data() context[‘form’] = form context[‘form_action’] = reverse(‘mymodel-add’) context[‘form_display’] = ‘show’ context[‘form_save_label’] = ‘Add’ return render(self.request, ‘templates/list.html’, context) Лучший ответ:

Во-первых, вы правы в своем наблюдении: вам обязательно нужно использовать get_queryset для фильтрации списка. Я предлагаю что-то вроде:

class MyModelList(AdminPageMixin, ListView): model = MyModel context_object_name = ‘object’ template_name = ‘template/list.html’ def get_queryset(self): qs = self.model.objects.all() search = self.request.GET.get(‘search’) if search: qs = qs.filter(advertiser__name__icontains=search) qs = qs.order_by(«-id») # you don’t need this if you set up your ordering on the model return qs

Во-вторых, если вам действительно нужно повторно использовать код между списком и другими представлениями, вам лучше написать отдельную функцию, чем использовать mixin.

Замечание: вам не нужен URL формы form_action в вашей форме; просто установите action=»» и он будет POST с тем же URL.

Ответ №1

Лучший способ – отфильтровать данные в ‘get_context_data’.

def get_context_data(self, **kwargs): context = super(MyModelAdd, self).get_context_data(**kwargs) context[‘form_action’] = reverse(‘mymodel-add’) context[‘form_display’] = ‘show’ context[‘object_list’] = MyModel.objects.all(user=self.request.user)# that will filter the user data return context

Оцените статью
Добавить комментарий