2

私は新しいアプリを始めており、クラス ベースのビューを採用するために最善を尽くしています。ああ、成長痛。ここで GET 変数から単純なフィルターを実行しようとしています。存在しない場合は、id desc で並べ替えられたすべてのオブジェクトを返したいです。存在する場合は、フィルター処理し、並べ替えて、フィルター処理されたリストを返します。

これを行うために 30 行以上のコードを書いているので、何か間違ったことをしているに違いありません。get_queryset() をオーバーライドしようとしましたが、考えてみると、このフィルタリングを行うには、 get_queryset() で self.request.GET['search'] を呼び出す必要があるかもしれません。これを達成する標準的な方法はありますか?

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

次に、問題を複雑にするために、ListView の get() または get_queryset() および get_context_data() メソッドを共有したい CreateView と UpdateView があります。Mixin で可能だと確信していますが、標準化された方法を探しています。提案?ListView のメソッドを共有したい CreateView を次に示します。

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)
4

2 に答える 2

4

まず、あなたの観察は正しいです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

次に、List と他のビューの間でコードを再利用する必要がある場合は、mixin を使用するよりも別の関数を作成する方がよいでしょう。

form_action補足:フォームに URLは必要ありません。設定するだけaction=""で、同じ URL に POST します。

于 2013-03-22T11:41:43.097 に答える