现有的表包括导航表 Nav 和文章表 Articles,Articles 中的数据会保存对应的 nav_id,意思为,找到导航栏中某个菜单下的全部文章,通用的方法是先在 Nav 表中查到这个导航的 id,再根据其 id 在 Articles 表中找具备这个 nav_id 的文章。代码以下:html
1 nav = models.Nav.objects.get('个人博客') 2 result = models.Article.objects.filter(nav=nav) #这里也能够写nav_id=nav.id
以上须要在两个表中查询的数据能够在一个表中实现前端
经过外键反向查询:python
1 nav = models.Nav.objects.get('个人博客') 2 result = nav.article_set.all() #查询导航下面全部的文章
目的:根据导航 id 显示对应的文章ajax
样式:前端带上参数 127.0.0.1:8000/index/?limit=10&page=2数据库
1 limit = request.GET.get('limit',page_limit) #20为默认值 2 page = request.GET.get('page',1)
此处的 page_limit 是配置在一个放常量的文件中,方便往后更改django
另外,post 请求取参数的方式与 get 相同,即: demo = request.POST.get() json
1 import django,os 2 from django.core.paginator import Paginator 3 4 # 分页怎么用 5 l = list(range(100)) 6 page_obj = Paginator(l,20) 7 8 print(page_obj.count) #总共多少数据 9 page1 = page_obj.get_page(1) 10 print(list(page1)) #获取第几页的数据 11 print(page_obj.num_pages) #总共分了几页 12 print(page_obj.page_range) #分页范围 13 print(page_obj.page_range[0]) 14 print(page_obj.page_range[-1])
以上用法为:后端
a. 给 Paginator 传两个参数,第一个是全部要分页的内容,第二个是每页的显示条数浏览器
b. 目前 page_obj 是一个含有全部分页信息的对象,它的用法有以上几种函数
c. 其中 page1 是具体到某一页的内容,它的用法以下:
1 page1 = page_obj.get_page(1) 2 print(page1.number) #当前的页码 3 page1.has_next() #是否有下一页 4 page1.has_other_pages() #是否有其余页 5 page1.has_previous() #是否有上一页 6 page1.next_page_number() #下一页的页码,若是没有下一页,则报错 7 page1.previous_page_number() #上一页的页码 8 page1.end_index() #末页 9 page1.start_index() #首页 10 obj = page1.paginator #获取分页的对象
根据以上的这些用法,咱们能够对前端页面的页码和翻页展现进行操做,首先,views 中定义 index 上面展现了获取浏览器传过来的参数的方法(limit 和 page),而后再根据这两个参数拿到具体要显示的内容返回给前端,如下是整个 index 的内容:
def index(request): #格式要求写request limit = request.GET.get('limit',page_limit) #默认值 page = request.GET.get('page',1) # post请求获取参数 # request.POST.get() # article = models.Article.objects.all() page_obj = Paginator(models.Article.objects.all().order_by('id'),limit) page_data = page_obj.get_page(page) dic = {'articles':page_data} return render(request,'index.html',dic)
获取到的 article 返回到 index 页面,这样就能在这个页面直接用这个数据。
而后在 index 页面对当前页面拿到的数据进行判断来展现翻页部分的功能,如下为翻页部分的逻辑,有个问题是 start_index 和 end_index 并不起做用,也就是首页喝末尾页用自带方法并未很好的实现
(调试过程当中发现末尾页还好,首页内容不许,我改为了拿返回的第一个的方式,可是末页还不会写)用首尾页这个方法的问题表如今,点了以后在 URL 一栏中 limit 和 page 的信息是错的
1 <ul class="pagination"> 2 {% if articles.has_other_pages %} 3 {# <li><a href="/index/?limit={{ page_limit }}&page={{ articles.start_index }}">⏪</a></li> start_index end_index不起做用#} 4 <li><a href="/index/?limit={{ page_limit }}&page={{ articles.paginator.page_range.0 }}">⏪</a></li> 5 {% endif %} 6 7 {% if articles.has_previous %} 8 <li><a href="/index/?limit={{ page_limit }}&page={{ articles.previous_page_number }}"><️</a></li> 9 {% endif %} 10 11 {% for num in articles.paginator.page_range %} 12 {% if articles.number == num %} 13 <li><a class="active" href="/index/?limit={{ page_limit }}&page={{ num }}">{{ num }}</a></li> 14 {% else %} 15 <li><a href="/index/?limit={{ page_limit }}&page={{ num }}">{{ num }}</a></li> 16 {% endif %} 17 {% endfor %} 18 19 {% if articles.has_next %} 20 <li><a href="/index/?limit={{ page_limit }}&page={{ articles.next_page_number }}">></a></li> 21 {% endif %} 22 23 {% if articles.has_other_pages %} 24 <li><a href="/index/?limit={{ page_limit }}&page={{ articles.end_index }}">⏩</a></li> 25 {% endif %} 26 </ul>
经过 127.0.0.1:8000/admin 便可访问,为后台添加管理员的操做:python manage.py createsuperuser
以后的用户能够在后台直接建立。
1.配表
Django 建立的工程中自带的一些东西就包含后台,相关内容在 admin.py 中,而初次打开后台的时候并不会把咱们现有的表展现出来,这时候须要在前面提到的 python 文件中配置一下:
1 from django.contrib import admin 2 from . import models 3 # Register your models here. 4 5 # admin.site.register(models.Nav) #与下方的class二选一 6 # admin.site.register(models.Article) 7 8 9 class NavAdmin(admin.ModelAdmin): 10 list_display = ['id','name','create_time'] 11 12 class ArticleAdmin(admin.ModelAdmin): 13 list_display = ['id','title','img','create_time'] #显示几列 14 search_fields = ['title','content'] 15 list_per_page = 5 16 17 class StudentAdmin(admin.ModelAdmin): 18 list_display = ['name','phone','money'] 19 20 admin.site.register(models.Article,ArticleAdmin) 21 admin.site.register(models.Nav,NavAdmin) 22 admin.site.register(models.Student,StudentAdmin)
以上配置包含了显示表中的哪些列,配好了表以后,就能够在后台很方便地对数据库表进行操做啦。
可是随之而来的还有另一个问题,就是在后台这样的前端界面输入的数据实际上是没有通过校验的,如何保证数据填写符合咱们的要求,就须要在前端增长校验。
以前学 Python 的时候,要作这件事可能就是对挨个的数据进行判断,如先非空检验,再各个字段去校验,这里的要简单许多,先简单罗列一下。
1 class StudentForm(forms.Form): 2 name = forms.CharField(min_length=2,max_length=10,required=True) #required=True表示必填,默认必填 3 phone = forms.CharField(min_length=11,max_length=11) 4 money = forms.FloatField(required=False,default=0,null=True) 5 # 自定义函数校验是否字段重复 6 def clean_phone(self): 7 '''钩子''' 8 phone = self.cleaned_data['phone'] 9 if models.Student.objects.filter(phone=phone): 10 return self.errors.add('手机号错误','手机号已经存在') 11 return phone 12 13 14 def student(request): 15 stu_form = StudentForm(request.POST) 16 if stu_form.is_valid(): 17 models.Student.objects.create(**stu_form.cleaned_data) 18 data = {"msg":"成功"} 19 else: 20 data = {"msg":"检验失败"} 21 return HttpResponse(json.dumps(data,ensure_ascii=False))
理解上还须要再回看视频。
以在后台添加文章为例,咱们须要两个 URL,一个用来展现添加文章的页面,另外一个用来向后端发送请求添加数据。
这时候能够写成两个 URL,但也能够写成一个,只须要在定义的时候将请求方法区分开便可。
1 def add_article(request): 2 if request.method == 'GET': 3 return render(request,'add.html') 4 else: 5 title = request.POST.get('title') 6 content = request.POST.get('content') 7 nav_id = request.POST.get('nav_id') 8 img = request.FILES.get('img') 9 models.Article.objects.create(title=title,content=content,nav_id=nav_id,img=img) 10 return HttpResponseRedirect('/index')
正常访问 add 页面时,是 get 请求,展现的是添加文章数据的页面,在 add.html 中,咱们定义了向后端发送请求为 post 方法。这样就能够实现各自的功能了。
不过这里 add.htnl 中写的是 form 表单的形式,周六有时间本身要尝试用 ajax 写一下。
文章待完善: