发布时间:2023-07-09 15:00
第一章 django安装与介绍
第二章 django基础使用
第三章 路由层
第四章 虚拟环境、django版本区别、视图层
第五章 模板层
第六章 模型层(上)
第七章 模型层(下)
第八章 ajax
第九章 sweetalert前端插件、序列化组件、批量数据操作、分页器、Forms组件(上)
下载地址
serializers是django自带的序列化数据的组件
使用JsonResponse来转化数据发送到前端
data_list = [] # [{}, {}, {}] 将json数据只作为列表套字典类型的
user_queryset = models.User.objects.all()# 对于QuerySet格式的数据是无法序列化的
for user_obj in user_queryset:
data_list.append({
\'uid\':user_obj.uid,
\'username\':user_obj.username,
\'password\':user_obj.password,
})
return JsonResponse(data_list,safe=False)
\"\"\" 使用jsonresponse可以高度定制我们需要的数据类型,缺点是数据多时使用麻烦
[{
\"uid\": 1,
\"username\": \"asdasd\",
\"password\": \"123123\"
}, {
\"uid\": 2,
\"username\": \"zxczxc\",
\"password\": \"123123\"
},...
]
\"\"\"
使用serializers来进行json序列化
user_queryset = models.User.objects.all()
ret = serializers.serialize(\'json\', user_queryset) # 使用
return HttpResponse(ret)
\"\"\"使用serializers可以快速生成json数据,格式也是固定的
[{
\"model\": \"app01.user\", 数据所属的表
\"pk\": 1, 数据主键
\"fields\": { 具体的数据
\"username\": \"asdasd\",
\"password\": \"123123\"
}
}, {
\"model\": \"app01.user\",
\"pk\": 2,
\"fields\": {
\"username\": \"zxczxc\",
\"password\": \"123123\"
}
}, ...
]
\"\"\"
django插入数据到数据库是很慢的,当我们一口气需要插入很多数据时需要优化数据的插入。
django插入数据通过models中的类进行的,所以我们先将数据转化为对应的类,可以大大节省django插入数据库时的转化对应表对象的过程,从而大大节省插入数据时间
def add_data(request):
user_list = []
for i in range(100000):
# 先用类产生一个对象
source_book_obj = models.User(username=f\'username{i}\',password=f\'password{i}\')
# 将对象追加到列表中
user_list.append(source_book_obj)
models.User.objects.bulk_create(user_list) # 批量插入
user_queryset = models.User.objects.all()
return render(request, \'add_data.html\', locals())
前端不可能将所有的数据全部展示到一页,应该考虑使用分页,每页展示一些,前端很多地方都需要分页所以有了分页的模块。
此处提供的自定义分页器模块需要搭配bootstrap来使用,也可以自行修改分页器和内容显示区域的样式
首先创建一个utils包
创建一个py文件在其中添加以下代码
class Pagination(object):
def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
\"\"\"
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
\"\"\"
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page < 1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page_num = per_page_num
# 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager
self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2)
@property
def start(self):
return (self.current_page - 1) * self.per_page_num
@property
def end(self):
return self.current_page * self.per_page_num
def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1
# 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1
page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append(\'\'\'
)
first_page = \'首页 \' % (1)
page_html_list.append(first_page)
if self.current_page <= 1:
prev_page = \'上一页 \'
else:
prev_page = \'上一页 \' % (self.current_page - 1,)
page_html_list.append(prev_page)
for i in range(pager_start, pager_end):
if i == self.current_page:
temp = \'%s \' % (i, i,)
else:
temp = \'%s \' % (i, i,)
page_html_list.append(temp)
if self.current_page >= self.all_pager:
next_page = \'下一页 \'
else:
next_page = \'下一页 \' % (self.current_page + 1,)
page_html_list.append(next_page)
last_page = \'尾页 \' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append(\'\'\'
\'\'\')
return \'\'.join(page_html_list)
视图函数:
from utils import mypage # 导入刚才创建的py文件
user_queryset = models.User.objects.all()
# 1.产生分页器对象
\'\'\'针对于Pagination有以下几个关键字参数
current_page: 当前页
all_count: 数据库中的数据总条数
per_page_num: 每页显示的数据条数
pager_count: 最多显示的页码个数
\'\'\'
page_obj = mypage.Pagination(current_page=request.GET.get(\'page\'),all_count=user_queryset.count())
# 2.产生分页数据对象
page_queryset = user_queryset[page_obj.start:page_obj.end]
return render(request,\'many_data.html\',locals())
显示层:
注意导入bootstrap
<div class=\"container\">
<div class=\"row\">
<div class=\"col-md-8 col-md-offset-2\">
{% for user in page_queryset %}
<p>{{ user.username }}p>
<p>{{ user.password }}p>
{% endfor %}
{{ page_obj.page_html|safe }}
div>
div>
div>
django提供的forms组件可以实现快速产生获取数据的标签、数据验证、错误信息的反馈
编写自己的Forms
参数 | 作用 |
---|---|
min_length | 字符串最小长度 |
max_length | 字符串最大长度 |
min_value | 数字最小位数 |
max_value | 数字最大位数 |
label | 对应的label值 |
required | 验证时可以为空 |
from django import forms
class MyForm(forms.Form):
# 用户名至少三个字符最多八个字符
username = forms.CharField(min_length=3,max_length=8, label=\"用户名\")
# 密码最小不能小于4 最大不能超过16
password = forms.CharField(min_length=6,max_length=16, label=\"密码\")
# 邮箱必须符合邮箱格式(@关键符号)
email = forms.EmailField(required=True, label=\"邮箱\")
data = request.POST
# 1.将数据传入实例化对象
form_obj = MyForm({\"username\":data.get(\'username\'), \"password\":data.get(\'password\'), \"email\":data.get(\'email\')}) # 放入对应的字典数据 可以使用 **data 直接传入
# 2.查看数据是否合法(全部合法结果才是True)
form_obj.is_valid()
# 3.查看不符合条件的数据及原因
form_obj.errors # 类似这种 {\'email\': [\'Enter a valid email address.\']}
# 4.查看符合条件的数据
form_obj.cleaned_data # 符合条件的数据 {\'username\': \'kdq\', \'password\': k12345}
forms组件只负责渲染获取用户数据的标签
form表单标签和提交按钮需要自己写
封装程度高 扩展性较差 主要用于快速生成页面测试功能
{{ form_obj.as_p }} {# 这种注释中label和input会渲染在p标签中 #}
通过下图可以看出label和input在p中
错误信息在ul li中
{{ form_obj.as_table }} <!-- 这种注释中lable和input直接渲染 -->
通过下图可可以看出label和input直接渲染
错误信息在ul li中
{{ form_obj.as_ul }} {# label和input渲染在li中 #}
通过下图可可以看出label和input渲染在li中
错误信息在li下的ul li中
封装程度低 扩展性较好 但是字段比较多的情况下不方便
此时form_obj.username.label获取的只是对应input的label文本需要自行定制样式
form_obj.username将会渲染出input
<form action=\"\" method=\"post\">
<div class=\"form-group\">
<label for=\"\">{{ form_obj.username.label }}</label>
{{ form_obj.username }}
</div>
<div class=\"form-group\">
<label for=\"\">{{ form_obj.password.label }}</label>
{{ form_obj.password }}
</div>
<div class=\"form-group\">
<label for=\"\">{{ form_obj.email.label }}</label>
{{ form_obj.email }}
</div>
<button type=\"submit\" id=\"logobtn\" class=\"btn btn-default\">登录</button>
</form>
高度定制化,同时可以使用模板语法快速渲染
<form action=\"\" method=\"post\">
{% for form in form_obj %}
<div class=\"form-group\">
<label>{{ form.label }}label>
{{ form }}
div>
{% endfor %}
<button type=\"submit\" id=\"logobtn\" class=\"btn btn-default\">登录button>
form>
forms类中填写的校验性参数前端浏览器会识别并添加校验操作,前端的验证操作是可以被轻易修改的,最好是在后端验证
form表单可以取消浏览器自动添加校验功能的操作
<form action=\"\" method=\"post\" novalidate>form> {# 只要添加novalidate就能不触发forms组件的验证 #}
错误信息的前端获取方式
{{ form.errors.0 }}
提示信息可以自定义
在对应字段中设置error_messages即可
from django import forms
class MyForm(forms.Form):
# 用户名至少三个字符最多八个字符
username = forms.CharField(min_length=3,max_length=8, label=\"用户名\", error_messages={
\'min_length\':\'用户名最短3位\',
\'max_length\':\'用户名最长8位\',
\'required\':\'用户名必填\'
})
# 密码最小不能小于4 最大不能超过16
password = forms.CharField(min_length=6,max_length=16, label=\"密码\")
# 邮箱必须符合邮箱格式(@关键符号)
email = forms.EmailField(required=True, label=\"邮箱\")