django进阶版2
批量插入数据
在一个表中插入很多条的数据,你应该很快就能想到用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一步到位,用哪种方法就显而易见了-。-
自定义分页器
这个东西听上去是不是有点d,凡是自定义的,总感觉是比一般的高端一点,反正我是这么认为的|^ _ ^|
这里只提供思路啊,代码就由你去实现了,fighting!
首先我们是不是需要定义一些变量来存总页数,数据总量,每页数据量等等。。。
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怎么会没有一个这样的模块给我们使用呢?
就不多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())
模块中封装的分页器是真他妈的香啊。。。
创建多表关系的3种方法
全自动
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.后面字段的顺序
由第三张表通过哪个字段查询单表 就把哪个字段放前面
form组件
万万没想到,从这里才开始重点,我太难了啊 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)
forms组件钩子函数
针对字段 你可以做额外的校验 通过钩子函数
局部钩子
# 当你需要对某一个字段数据进行额外的一些列校验 你可以考虑使用钩子函数
# 针对单个字段的 使用局部钩子
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开头')],
)
改变input框的属性值
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'})
django进阶版2的更多相关文章
- django进阶版4
目录 1 Auth模块是什么 2 auth模块常用方法 authenticate() login(HttpRequest, user) logout(request) is_authenticated ...
- django进阶版3
hello... cookie与session 为什么会有cookie和session? 由于http协议是无状态的 无法记住用户是谁 cookie cookie是保存在客户端浏览器上的键值对 是服务 ...
- django进阶版1
目录 字段中choice参数 MTV与MVC模型 AJAX(*********) Ajax普通请求 Ajax传json格式化数据 Ajax传文件 序列化组件 Ajax+sweetalert 字段中ch ...
- python学习-- django 2.1.7 ajax 请求 进阶版
#原来版本 $.get("/add/",{'a':a,'b':b}, function(ret){ $('#result').html(ret)}) #进阶版 $.get(&qu ...
- zip伪加密文件分析(进阶版)
作者近日偶然获得一misc题,本来以为手到擒来,毕竟这是个大家都讨论烂了的题,详情访问链接http://blog.csdn.net/ETF6996/article/details/51946250.既 ...
- Python之路,Day16 - Django 进阶
Python之路,Day16 - Django 进阶 本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproj ...
- django进阶补充
前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...
- django进阶-3
先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...
- django进阶-4
前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...
随机推荐
- Flask-认识flask
Python 现阶段三大主流Web框架 Django Tornado Flask 对比 百度百科 1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, ...
- JS基础_垃圾回收(GC)
垃圾回收(GC) 程序运行过程中也会产生垃圾,这些垃圾积攒过多以后,会导致程序运行的速度过慢,所以我门需要一个垃圾回收的机制,来处理程序运行过程中产生的垃圾 当一个对象没有任何的变量或属性对它进行引用 ...
- Nginx-HTTP之listen指令解析
1. ngx_http_core_listen static char * ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void ...
- CentOS 上 Jenkins 的安装
Jenkins 的前身是 Hudson. Jenkins 是一款开源 CI&CD 软件,用于自动化各种任务,包括构建.测试和部署软件. Jenkins 支持各种运行方式,可通过系统包.Dock ...
- fastcgi代理
一.fastcgi代理 1.示意图 2.fastcgi 代理配置语法 a.设置PHP服务代理地址 Syntax: fastcgi_pass address; Default: — Context: l ...
- Linux服务器端使用tcpdump抓redis报文
yum update yum install tcpdump tcpdump host -i ens192 -w /tmp/redis-zsetcapture.cap 其中ens192是网卡名, /t ...
- Python3 编程第一步_斐波纳契数列_连续赋值
# Fibonacci series: 斐波纳契数列 # 两个元素的总和确定了下一个数 a, b = 0, 1 while b < 10: print(b) a, b = b, a+b # 1 ...
- python基础学习19,01
听说python入门很容易,所以想试试对我这个零基础会不会很友好呢.做随笔也顺便督促自己不要轻易放弃学习. #登录接口 print("请输入用户名密码") _username = ...
- 鸟哥私房菜基础篇:例行性工作排程 (crontab)习题
猫宁!!! 参考:http://cn.linux.vbird.org/linux_basic/0430cron.php 1-今天假设我有一个命令程序,名称为: ping.sh 这个档名!我想要让系统每 ...
- python入门踩坑
问题1:ImportError: No module named requests 解决:一般报这种错误就是目前还没有这个方法的类库,需要下载或在升级类库.打开cmd命令,输入python -m pi ...