在基于Django类的视图中重写get()以进行筛选

在基于Django类的视图中重写get()以进行筛选,django,django-class-based-views,Django,Django Class Based Views,我正在启动一个新的应用程序,我正在尽最大努力接受基于类的视图。啊,成长的烦恼。我试图从一个GET变量中进行一个简单的筛选,如果它不存在,我想返回按id desc排序的所有对象,如果存在,我想筛选、排序并返回筛选列表 我正在写30多行代码来做这件事,所以我一定是做错了什么,对吗?我尝试重写get_queryset,现在我想起来了,也许我应该在get_queryset中调用self.request.get['search']来执行此筛选。有没有标准的方法来实现这一点 class MyModelLis

我正在启动一个新的应用程序,我正在尽最大努力接受基于类的视图。啊,成长的烦恼。我试图从一个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
其次,让事情复杂化的是,我有一个CreateView和一个UpdateView,我想共享ListView的get或get_queryset和get_context_数据方法。我确信这是有可能的,但再一次,我正在寻找一个标准化的方法来做它。建议?下面是我想分享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)

首先,您的观察是正确的:您肯定应该使用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;只需设置action=它就会发布到同一个URL。

首先,您的观察是正确的:您肯定应该使用get\u 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;只需设置action=它就会发布到相同的URL。

最好的方法是在“获取上下文数据”中过滤数据

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's will filter the user data
    return context

最好的方法是在“获取上下文数据”中过滤数据

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's will filter the user data
    return context

“CBV并不一定意味着更少的共同感谢,”萨缪尔这样评论。我将把它添加到我的文档字符串中;基于类的视图是一种痛苦,但随着您更好地重构基类,它会慢慢变得更好。CBV并不一定意味着更少的代码谢谢@Samuele的观察。我将把它添加到我的文档字符串中;基于类的视图是一种痛苦,但随着您更好地重构基类,它会慢慢变得更好。谢谢!我之所以使用form_操作,是因为我在MyModelEdit中对其进行了不同的设置,并使用了相同的表单。context['form_action']=在CreateView视图中反转'mymodel-add',在EditView中上下文['form_action']=反转'mymodel-edit',再次调用相同的html文件。再次感谢。第二,如果您真的需要在列表和其他视图之间重用代码,最好编写一个单独的函数,而不是使用mixin。-你知道这方面的好例子吗?不应该是这样的:if search:qs=qs.filteradvertiser\uuu name\uuuu icontains=search?谢谢!我之所以使用form_操作,是因为我在MyModelEdit中对其进行了不同的设置,并使用了相同的表单。context['form_action']=在CreateView视图中反转'mymodel-add',在EditView中上下文['form_action']=反转'mymodel-edit',再次调用相同的html文件。再次感谢。第二,如果您真的需要在列表和其他视图之间重用代码,最好编写一个单独的函数,而不是使用mixin。-你知道这方面的好例子吗?不应该是这样的:if search:qs=qs.filteradvertiser\uuu name\uuuu icontains=search吗?