- 分页
关于分页,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显示那一块即可。
这是文档里的一段,我们可以直接拿来使用。
{% if all_orgs.has_previous %}
- 上一页
{% endif %}
- {{ all_orgs.number }}
{% if all_orgs.has_next %}
- 下一页
{% endif %}
我们来看一下效果。
OK,没有问题,我们点下一页看看。
第一页去哪了?这里我们还需要做一些操作。为了省去这些操作,我们来看一下这个插件。
- 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
{% if all_orgs.has_previous %}
- 上一页
{% else %}
{% endif %}
{% for page in all_orgs.pages %}
{% if page %}
{% ifequal page all_orgs.number %}
- {{ page }}
{% else %}
- {{ page }}
{% endifequal %}
{% endif %}
{% endfor %}
{% if all_orgs.has_next %}
- 下一页
{% else %}
{% endif %}
这里有一个十分重要的地方,在我们使用for 遍历 我们all_orgs的时候我们需要使用 all_orgs.object_list也就是下面这样
{% for org in all_orgs.object_list %}
xxxx
{% endfor %}
如果没写会有什么效果呢?
会有一个这样的错误。一定要注意这里!!!
- 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()的使用。
意思是你可以对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'机构类别')
数据库里。
但有时,我们需要在html中显示后面的培训,高效,个人等信息。这时候我们就需要使用get_xxx(字段名)_display了。我们先恢复之前注释的OrganizationListView的get方法,然后我们将这里的学习人数改为机构名称,只是用来学习用,这里应该还是students_num才对。
html中修改
学习人数:{{ org.get_category_display }}
没毛病,今天就到这了。
资料下载地址
资料直接下载