美文网首页python学习实践WEB前端程序开发程序员
Django学习记录第十天—分页+ModelForm

Django学习记录第十天—分页+ModelForm

作者: Rokkia | 来源:发表于2017-07-03 20:50 被阅读210次
    • 分页

    关于分页,Django官方文档中有,我们来看一下。

    这里我们还是拿之前的org-list.html来改写

    首先我们导入头文件

    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    

    然后我们来编写一下我们的get请求。其实这里我们只需要将官网的代码贴过去,然后做下修改即可。我们将之前的get函数注释掉。

     def get(self, request):
            all_orgs = Organization.objects.all()
            paginator = Paginator(all_orgs, 1)  #这里的25意思是每一页要显示几个,由于我们只有3个数据,这里我们就每一页显示一个
            page = request.GET.get('page')
            try:
                contacts = paginator.page(page) 
            except PageNotAnInteger:
                # If page is not an integer, deliver first page.
                contacts = paginator.page(1)
            except EmptyPage:
                # If page is out of range (e.g. 9999), deliver last page of results.
                contacts = paginator.page(paginator.num_pages)
            #由于html中我们使用的就是all_orgs所以这里我们也用all_orgs来传递,这样我们html中基本就可以不用修改了
            return render(request, 'org-list.html', {'all_orgs': contacts})
    

    这里修改完成后我们只需要修改一下我们的html里面即可。由于我们传递过去的就是all_orgs,所以这里我们只需要修改一下Paginator显示那一块即可。

    image.png

    这是文档里的一段,我们可以直接拿来使用。

    <div class="pageturn">
        <ul class="pagelist">
                {% if all_orgs.has_previous %}
                     <li class="long"><a href="?page={{ all_orgs.previous_page_number }}">上一页</a></li>
                {% endif %}
    
                <span class="current">
                    <li><a href="?page={{ all_orgs.number }}" class="page">{{ all_orgs.number }}</a></li>
                </span>
    
                {% if all_orgs.has_next %}
                    <li class="long"><a href="?page={{ all_orgs.next_page_number }}">下一页</a></li>
                {% endif %}
        </ul>
    </div>
    

    我们来看一下效果。

    image.png

    OK,没有问题,我们点下一页看看。

    image.png

    第一页去哪了?这里我们还需要做一些操作。为了省去这些操作,我们来看一下这个插件

    • django-pure-pagination

    使用也很简单,我们只需要按照上面说的一步一步来就OK了。同时呢,这个插件也是基于django的pagination来编写的。
    我们来搞一下。
    来到环境里安装一下django-pure-pagination

    pip install django-pure-pagination
    

    然后

    INSTALLED_APPS = (
        ...
        'pure_pagination',
    )
    

    再然后,重写一下我们的view

        #注意这里需要导入头文件
        from pure_pagination import Paginator, EmptyPage, PageNotAnInteger
        
        def get(self, request):
            all_orgs = Organization.objects.all()
            try:
                page = request.GET.get('page', 1)
            except PageNotAnInteger:
                page = 1
            #######
            p = Paginator(all_orgs, 1, request=request)
            objects = p.page(page)
            return render(request, 'org-list.html', {
                'all_orgs': objects,
            })
    

    这里需要十分注意Paginator实例化时,github给了两个参数,其实这里需要3个中间的1就是每一页要显示几个。也就是上面加###的地方。

    然后我们来修改一下html

    <div class="pageturn">
        <div class="pagination">
            <ul class="pagelist">
                {% if all_orgs.has_previous %}
                    <li class="long"><a href="?page={{ all_orgs.previous_page_number }}">上一页</a></li>
                {% else %}
                {% endif %}
                {% for page in all_orgs.pages %}
                    {% if page %}
                        {% ifequal page all_orgs.number %}
                            <li class="active"><a href="?page={{ page }}">{{ page }}</a></li>
                        {% else %}
                            <li><a href="?page={{ page }}" class="page">{{ page }}</a></li>
                        {% endifequal %}
                    {% endif %}
                {% endfor %}
                {% if all_orgs.has_next %}
                     <li class="long"><a href="?page={{ all_orgs.next_page_number }}">下一页</a></li>
                {% else %}
                {% endif %}
            </ul>
        </div>
    </div>
    

    这里有一个十分重要的地方,在我们使用for 遍历 我们all_orgs的时候我们需要使用 all_orgs.object_list也就是下面这样

    {% for org in all_orgs.object_list %}
    xxxx
    {% endfor %}
    

    如果没写会有什么效果呢?

    image.png

    会有一个这样的错误。一定要注意这里!!!

    • ModelForm

    我们知道了Form的使用,那么ModelForm有什么用呢 ?
    为了好解释这个用法呢,我们来假设这样一个场景,假如,我们有一个类需要保存org的一些信息如下面这些字段。这个类我们叫做ChangOrgModel

    course_num = models.IntegerField(default=0, verbose_name=u'课程数')
    students_num = models.IntegerField(default=0, verbose_name=u'学习人数')
    address = models.CharField(max_length=200, verbose_name=u'地址')
    

    如果我们使用form我们需要怎么做呢。我们大概需要这样做。

    class OrgModelForm(forms.Form):
        course_num = forms.IntegerField()
        students_num = forms.IntegerField()
        address = forms.CharField(max_length=200)
    

    我们不难发现,我们的Form定义跟Model的定义基本没什么区别,应该加max_length的时候还是需要加,我们相当于是重写了一遍,其次,这里只有三个,并没有感觉,当有7、8甚至更多的时候,这样重复操作就很让人受不了了。所以这里我们可以使用ModelForm
    定义我们的ModelForm

    class OrgModelForm(forms.ModelForm):
        class Meta:
            model = Organization
            fields = ['course_num', 'students_num', 'address']
    

    就这样就OK了,model就是要绑定哪一个Model,fileds是指定想要验证的属性。
    view中使用

    def post(self, request):
            form = OrgModelForm(request.POST)
            if form.is_valid():
                form.save(commit=True)
                return render....
    

    这里由于是虚拟的场景,所以这里并没有实现什么,这里需要注意的地方是,这里的form.save()里一定要写commit=True否则不能保存哦!

    同时另外一种使用方法

    def post(self, request):
        org_model =  ChangOrgModel()
        form = UploadAvatarForm(request.POST, instance=org_model)
        if form.is_valid():
            form.save()
    

    这里我们在实例化ModelForm的时候直接将org_model对象穿过去,这样有什么效果呢,我们直接使用save就可以了。
    更多的理解可以来这里看一下。文档里还有一个比价重要的地方。这里介绍了一个叫做clean()的使用。

    image.png

    意思是你可以对pub_date field做一些额外的验证操作。也就是我们可以来自定义这个字段的验证,只需要重写def clean_pub_date(self):即可。

    • html中使用choice

    这里很有意思,我们在定义好我们CharField中,包含choices时,我们数据库里存的其实是前一个值,而往往我们需要显示后面的那个值,如:

    category = models.CharField(max_length=10, choices=(('px', u'培训'), ('gx', u'高校'), ('gr', u'个人')), default='gx', verbose_name=u'机构类别')
    

    数据库里。

    image.png

    但有时,我们需要在html中显示后面的培训,高效,个人等信息。这时候我们就需要使用get_xxx(字段名)_display了。我们先恢复之前注释的OrganizationListView的get方法,然后我们将这里的学习人数改为机构名称,只是用来学习用,这里应该还是students_num才对。

    image.png

    html中修改

    学习人数:<span>{{ org.get_category_display }}</span>
    
    image.png

    没毛病,今天就到这了。

    资料下载地址
    资料直接下载

    坚持三十天,一起加油!

    相关文章

      网友评论

        本文标题:Django学习记录第十天—分页+ModelForm

        本文链接:https://www.haomeiwen.com/subject/fkgacxtx.html