目录html
在一个表中插入不少条的数据,你应该很快就能想到用create,然而事实是这样吗?前端
def index(request): book_list=[] for i in range(1000): #models.Book.objects.create(title=f'第{i}本书') book=models.Book(title=f'第{i}本书') book_list.append(book) models.Book.objects.bulk_create(book_list) book_query=models.Book.objects.all() return render(request,'index.html',locals())
<body> {%for i in book_query%} <p> {{i.title}} </p> {%endfor%} </body>
就像上面注释的代码是否是你的想法呢,想法能够,但实现着实困难了点,一旦数据多了,就会形成数据库的庞大压力,而使用bulk_create一步到位,用哪一种方法就显而易见了-。-python
这个东西听上去是否是有点d,凡是自定义的,总感受是比通常的高端一点,反正我是这么认为的|^ _ ^|数据库
这里只提供思路啊,代码就由你去实现了,fighting!django
首先咱们是否是须要定义一些变量来存总页数,数据总量,每页数据量等等。。。后端
current_page=request.GET.get('page',1) #获取用户想要访问的页码数,若是没有则默认第一页 current_page=int(current_page) #转成整形 per_page_num=10 #定义一下每页须要多少条数据,这里定义成10条哦 start_page=(current_page-1)*per_page_num #每一页的初始位置 end_page=current_page*per_page_num #每一页的末尾位置 book_query=models.Book.objects.all() all_count=book_query.count() #统计数据总量 #这里须要用到一个divmod方法,来求出须要的总页数 page_num,more=divmod(all_count,per_page_num) if more: page_num+=1 page_html='' #这是待会要传回前端页面的标签 x=current_page #先保存一下,以避免待会数据发生变化 if current<6: #小于第6页,就不会再往前滑动 current=6 for i in range(current_page-5,current_page+6): #一共展现11页 if x=i: page_html+=''<li class="active"><a href="?page=%s">%s</a></li>'%(i,i)'#设置高亮 else: page_html += '<li><a href="?page=%s">%s</a></li>' % (i, i) book_query=book_query[start_page:end_page] return render(request,'index.html',locals())
{% for book_obj in book_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {{ page_html|safe }} <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav>
哎,嘴上虽说着不写代码了,手仍是很诚实的,真是没办法啊-_-安全
以上就是自定义分页器的内容了,不过呢,强大的python怎么会没有一个这样的模块给咱们使用呢?app
就很少bb了,直接上代码函数
from app01.utils.mypage import Pagination def login(request): book_query=models.Book.objects.all() current_page=request.GET.get('page',1) all_count=book_queryset.count() #实例化产生对象 page_obj=Pagination(current_page=current_page,all_count=all_count) #切片操做 page_queryset=page_queryset[page_obj.start:page_obj.end] return render(request,'login.html',locals())
模块中封装的分页器是真他妈的香啊。。。post
orm一上来就本身动(手建表),这个就不用我多说了吧,你们都懂的(邪魅一笑...)
好处在于他会帮你建立第三张表,但不能对第三张表中的字段进行二次操做,扩展性就比较差了
class Book(models.Model): ... authors = models.ManyToManyField(to='Author') class Author(models.Models): ...
这个一看就感受很麻烦了吧,并且居然还有另外的缺点,orm查询时不少方法都不支持,查询起来就比较麻烦,很少说,果断放弃吧
class Book(models.Model): ... class Author(models.Models): ... class Book2Author(models.Model): book_id = models.ForeignKey(to='Book') author_id = models.ForeignKey(to='Author') create_time = models.DateField(auto_now_add=True) ...
orm亲儿子,懂吧?
推荐指数6颗星,手动建表,可是会通知orm这表是本身建的,orm提供各类方法就好了,不过有四种方法仍然不支持add,set,remove,clear,不过问题不大哈
class Book(models.Model): ... authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book','author')) ''' class Author(models.Model): ... books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book')) ''' class Book2Author(models.Model): book = models.ForeignKey(to='Book') author = models.ForeignKey(to='Author') create_time = models.DateField(auto_now_add=True) ... # 1.半自动 必定要加两个额外的参数 through='Book2Author', through_fields=('book','author') # 2.后面字段的顺序 由第三张表经过哪一个字段查询单表 就把哪一个字段放前面
万万没想到,从这里才开始重点,我太难了啊 T.T
开始了啊,加入咱们要设计一个注册页面,用户name不能包含dsb这串字符,密码不小于3位,这显然比较简单
def reg(request): back_dic={'username':'','password':''} if request.method=='POST': username=request.POST.get('username') password=request.POSt.get('password') if 'dsb' in username: back_dic['username']='你输入的用户名不符合社会主义核心价值观' if len(password)<3: back_dic['password']='过短了哦,嫌弃ing' return render(request,'reg.html',local())
<form action="" method="post"> <p>username: <input type="text" name="username"> <span style="color: red">{{ back_dic.username }}</span> </p> <p>password:<input type="text" name="password"> <span style="color: red">{{ back_dic.password }}</span> </p> <input type="submit"> </form>
这样写起来,若是有不一样的输入错误状况显然比较麻烦,因此就要用到form组件了
首先,写一个类
from django import forms class Myform(forms.Form): username=forms.CharField(min_length=3,max_length=8) password=forms.CharField(min_length=3,max_length=8) email=forms.EmailField() #如何校验数据 from app01 import views obj=views.Myform({'username':'jason','password':'123','email':'123'}) #判断数据是否合法 obj.is_valid() #查看符合条件的数据 obj.cleaned_data #查看不符合条件的数据 obj.errors #须要注意的是,全部的参数必须传值,能够多传,不能少传
封装成度过高,可扩展性差
<p> {{form_obj.as_p}} {{form_obj.as_ul}} </p>
<p> {{ form_obj.username.label }}{{ form_obj.username }} </p> <p> {{ form_obj.password.label }}{{ form_obj.password }} </p> <p> {{ form_obj.email.label }}{{ form_obj.email }} </p>
手写代码量太多,明显不方便
推荐使用
{% for foo in form_obj %} <p>{{ foo.label }}{{ foo }}</p> {% endfor %}
因为form组件会自动前端校验数据,但前端校验又不太安全,因此咱们取消他,来后端校验
在前端中的form表单中添加参数novalidata便可
<!--展现错误信息 用对象点errors.0--> <form action="" method="post" novalidate> {% for foo in form_obj %} <p> {{ foo.label }}:{{ foo }} <span style="color: red">{{ foo.errors.0 }}</span> </p> {% endfor %} <input type="submit"> </form>
设置错误信息
from django import forms class MyRegForm(forms.Form): username = forms.CharField(min_length=3,max_length=8,label='用户名', error_messages={ 'min_length':'用户名最短三位', 'max_length':'用户名最长八位', 'required':'用户名不能为空' },initial='我是初始值',required=False ) password = forms.CharField(min_length=3,max_length=8,label='密码',error_messages={ 'min_length':'密码最短三位', 'max_length':'密码最长八位', 'required':'密码不能为空' }) email = forms.EmailField(label='邮箱',error_messages={ 'required':'邮箱不能为空', 'invalid':'邮箱格式不正确' },required=False)
针对字段 你能够作额外的校验 经过钩子函数
# 当你须要对某一个字段数据进行额外的一些列校验 你能够考虑使用钩子函数 # 针对单个字段的 使用局部钩子 def clean_username(self): username = self.cleaned_data.get('username') if 'dsb' in username: # 给username字段下面提示错误信息 self.add_error('username','用户名不符合社会主义核心价值观') return username
def clean(self): password=self.cleaned_data.get('password') if not password == confirm_password: self.add_error('confirm_password','两次密码不一致') return self.cleaned_data
from django import forms from django.forms import Form from django.core.validators import RegexValidator class MyForm(Form): user = forms.CharField( validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')], )
widget= widgets.TextInput() widget=widgets.PasswordInput() 如何让forms组件渲染出来的input框有form-control类属性 widget= widgets.TextInput(attrs={'class':'form-control others'}) # 若是有多个类属性 空格隔开 widget=widgets.PasswordInput(attrs={'class':'form-control others'})