Django的:在基于类的ListView搜索表单 [英] Django: Search form in Class Based ListView

查看:1013
本文介绍了Django的:在基于类的ListView搜索表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现类的ListView基其中显示选择的表集。如果站点请求在第一时间,应显示的数据集。我想preFER一个POST提交,但得到的也就好了。

这是一个问题,这是很容易与基于功能视图,但基于类的意见我也很难左右让我的头处理。

我的问题是,我得到一个不同的号码错误的,这是由我有限的归类为本次的理解造成的。我已阅读各种文档和我理解的观点直接查询请求,但只要我想一个表单添加到查询语句中,我遇到不同的错误。对于下面的code,我收到一个 ValueError错误:无法使用无作为查询值

什么将是依赖于表单提交,基于类的ListView(否则选择整个数据库)?最佳实践工作流程

这是我的样本code:

models.py

 类档案(models.Model):
    名称= models.CharField(_(名称),MAX_LENGTH = 255)    高清__uni code __(个体经营):
        回报%名称'%{'名':self.name}    @staticmethod
    高清get_queryset(PARAMS):        DATE_CREATED = params.get('DATE_CREATED')
        关键字= params.get(关键字)
        展示Qset = Q(pk__gt = 0)
        if关键字:
            展示Qset&安培; = Q(title__icontains =关键字)
        如果DATE_CREATED:
            展示Qset&安培; = Q(date_created__gte = DATE_CREATED)
        返回展示Qset

forms.py

 类ProfileSearchForm(forms.Form):
    名称= forms.CharField(必填= FALSE)

views.py

 类ProfileList文件(ListView控件):
    模型=简介
    form_class = ProfileSearchForm
    context_object_name ='个人资料'
    TEMPLATE_NAME ='页/型材/ list_profiles.html
    型材= []
    高清后期(个体经营,请求,* ARGS,** kwargs):
        self.show_results =假
        self.object_list = self.get_queryset()
        形式= form_class(s​​elf.request.POST或无)
        如果form.is_valid():
            self.show_results = TRUE
            self.profiles = Profile.objects.filter(name__icontains = form.cleaned_data ['名'])
        其他:
            self.profiles = Profile.objects.all()
        返回self.render_to_response(self.get_context_data(object_list中= self.object_list,形式=形式))    高清get_context_data(个体经营,** kwargs):
        上下文=超(ProfileList文件,个体经营).get_context_data(** kwargs)
        如果没有self.profiles:
            self.profiles = Profile.objects.all()
        context.update({
            配置文件:self.profiles
        })
        回报方面

下面我添加了没有工作的FBV。 我怎么能这个功能转化为CBV?
这似乎是在基于函数的观点很简单,但不是基于类的意见。

 高清list_profiles(要求):
    form_class = ProfileSearchForm
    模型=简介
    TEMPLATE_NAME ='页/型材/ list_profiles.html
    paginate_by = 10    形式= form_class(request.POST或无)
    如果form.is_valid():
        profile_list = model.objects.filter(name__icontains = form.cleaned_data ['名'])
    其他:
        profile_list = model.objects.all()    分页程序=分页程序(profile_list,10)#每页显示10个联系人
    页= request.GET.get(页)
    尝试:
        型材= paginator.page(页)
    除了PageNotAnInteger:
        型材= paginator.page(1)
    除了EmptyPage:
        型材= paginator.page(paginator.num_pages)    返回render_to_response(TEMPLATE_NAME,
            {形式:形式的个人资料:供应商,},
            context_instance = RequestContext的(要求))


解决方案

我觉得你的目标是试图基于表单提交,以过滤查询集如果是这样,通过使用GET:

 类ProfileSearchView(ListView控件)
    TEMPLATE_NAME ='/your/template.html
    模型=人    高清get_queryset(个体经营):
        尝试:
            名称= self.kwargs ['名']
        除:
            名称=''
        如果(名称=''!):
            object_list中= self.model.objects.filter(name__icontains =名称)
        其他:
            object_list中= self.model.objects.all()
        返回object_list中

然后,所有你需要做的是写一个 GET 方法来呈现模板和背景。

也许不是最好的方法。通过使用上述code,你不需要定义一个Django的形式。

下面是它的工作原理:基于类的观点分离的方式来呈现模板,处理表单等等。像 GET 处理GET响应,处理POST响应, get_queryset 的get_object 是自我解释,等等。最简单的办法知道什么是可用的方法,启动一个shell,然后键入:

从django.views.generic进口的ListView 如果你想知道关于的ListView

然后键入 DIR(ListView控件)。在那里,你可以看到定义的所有方法和就往源$ C ​​$ C去了解它。使用了 get_queryset 方法来获取查询集。为什么不直接定义它像这样,它也能工作:

 类FooView(ListView控件):
    TEMPLATE_NAME ='foo.html'
    查询集= Photo.objects.all()#或其他任何

我们可以做到这一点像上面,但是我们不能用这种方法进行动态过滤。通过使用 get_queryset 我们可以做动态过滤,用我们甲肝任何数据/价值/信息,这意味着我们也可以使用名称参数是由 GET ,以及对 kwargs ,或在这种情况下, self.kwargs [some_key] ,其中 some_key 是您指定的任何参数

I am trying to realize a Class Based ListView which displays a selection of a table set. If the site is requested the first time, the dataset should be displayed. I would prefer a POST submission, but GET is also fine.

That is a problem, which was easy to handle with function based views, however with class based views I have a hard time to get my head around.

My problem is that I get a various number of error, which are caused by my limited understanding of the classed based views. I have read various documentations and I understand views for direct query requests, but as soon as I would like to add a form to the query statement, I run into different error. For the code below, I receive an ValueError: Cannot use None as a query value.

What would be the best practise work flow for a class based ListView depending on form entries (otherwise selecting the whole database)?

This is my sample code:

models.py

class Profile(models.Model):
    name = models.CharField(_('Name'), max_length=255)

    def __unicode__(self):
        return '%name' % {'name': self.name}

    @staticmethod
    def get_queryset(params):

        date_created = params.get('date_created')
        keyword = params.get('keyword')
        qset = Q(pk__gt = 0)
        if keyword:
            qset &= Q(title__icontains = keyword)
        if date_created:
            qset &= Q(date_created__gte = date_created)
        return qset

forms.py

class ProfileSearchForm(forms.Form):
    name = forms.CharField(required=False)

views.py

class ProfileList(ListView):
    model = Profile
    form_class = ProfileSearchForm
    context_object_name = 'profiles'
    template_name = 'pages/profile/list_profiles.html'
    profiles = []


    def post(self, request, *args, **kwargs):
        self.show_results = False
        self.object_list = self.get_queryset()
        form = form_class(self.request.POST or None)
        if form.is_valid():
            self.show_results = True
            self.profiles = Profile.objects.filter(name__icontains=form.cleaned_data['name'])
        else:
            self.profiles = Profile.objects.all()
        return self.render_to_response(self.get_context_data(object_list=self.object_list, form=form))

    def get_context_data(self, **kwargs):
        context = super(ProfileList, self).get_context_data(**kwargs)
        if not self.profiles:
            self.profiles = Profile.objects.all()
        context.update({
            'profiles': self.profiles
        })
        return context

Below I added the FBV which does the job. How can I translate this functionality into a CBV? It seems to be so simple in function based views, but not in class based views.

def list_profiles(request):
    form_class = ProfileSearchForm
    model = Profile
    template_name = 'pages/profile/list_profiles.html'
    paginate_by = 10

    form = form_class(request.POST or None)
    if form.is_valid():
        profile_list = model.objects.filter(name__icontains=form.cleaned_data['name'])
    else:
        profile_list = model.objects.all()

    paginator = Paginator(profile_list, 10) # Show 10 contacts per page
    page = request.GET.get('page')
    try:
        profiles = paginator.page(page)
    except PageNotAnInteger:
        profiles = paginator.page(1)
    except EmptyPage:
        profiles = paginator.page(paginator.num_pages)

    return render_to_response(template_name, 
            {'form': form, 'profiles': suppliers,}, 
            context_instance=RequestContext(request))

解决方案

I think your goal is trying to filter queryset based on form submission, if so, by using GET :

class ProfileSearchView(ListView)
    template_name = '/your/template.html'
    model = Person

    def get_queryset(self):
        try:
            name = self.kwargs['name']
        except:
            name = ''
        if (name != ''):
            object_list = self.model.objects.filter(name__icontains = name)
        else:
            object_list = self.model.objects.all()
        return object_list

Then all you need to do is write a get method to render template and context.

Maybe not the best approach. By using the code above, you no need define a django form.

Here's how it works : Class based views separates its way to render template, to process form and so on. Like, get handles GET response, post handles POST response, get_queryset and get_object is self explanatory, and so on. The easy way to know what's method available, fire up a shell and type :

from django.views.generic import ListView if you want to know about ListView

and then type dir(ListView). There you can see all the method defined and go visit the source code to understand it. The get_queryset method used to get a queryset. Why not just define it like this, it works too :

class FooView(ListView):
    template_name = 'foo.html'
    queryset = Photo.objects.all() # or anything

We can do it like above, but we can't do dynamic filtering by using that approach. By using get_queryset we can do dynamic filtering, using any data/value/information we hav, it means we also can use name parameter that is sent by GET, and its available on kwargs, or in this case, on self.kwargs["some_key"] where some_key is any parameter you specified

这篇关于Django的:在基于类的ListView搜索表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆