报错
data = UserInfo.objects.filter(id=nid)
# 出现了报错
# AttributeError: 'QuerySet' object has no attribute '_meta'
# data = UserInfo.objects.filter(id=nid).first()
部门编辑
正则表达式
基于django更简便的方法
# url.py中
path('user/<int:uid>/edit/', views.user_edit),
# views.py
def user_edit(request, uid):
data = UserInfo.objects.filter(id = uid).first()
return render(request, 'user_eidt.html', {"data" : data})
# user_list.html
<div>
<a href="/user/{{ data.id }}/edit/">编辑</a>
</div>
# user_add.html
<input value="{{ data }}">
页面模板的继承
<-- 父类 layout.html -->
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
<--子类 user_add.html-->
{% extends 'layout.html' %}
{% block content %}
<div>首页</div>
{% endblock %}
django中views.py中
datetime转字符串
from datetime import datetime
dt = datetime.now()
res = dt.strftime("%Y-%m-%d")
对象.get_gender_display()
其中gender在数据库中含有choices属性
对象.depart.title()
直接获取外键中的title属性
前端html中
datetime转字符串
对象.get_gender_display()
{% for a in all %}
<div>{{a.create_time|data:"Y-m-d"}}</div>
<div>{{a.get_gender_display}}</div>
{% endfor %}
新建用户
原始方法
对于gender_choices的1、2对应男、女
对于department对应部门title
我们传数据的时候,在views.py页面
context = {
'gender' : UserInfo.gender_choices,
'dep' : Department.objects.all(),
}
return render(request, "user_add.html", {"content" : context})
前端中
{% for a in gender %}
<option value="{{a.0}}">{{a.1}}</option>
{% endfor %}
{% for b in dep %}
<option value="{{b.id}}">{{b.title}}</option>
{% endfor %}
Django组件
Form组件
# views.py
class MyForm(Form):
# widget=forms.Input属性,使传给前端之后,显示为一个input框
name = CharField(widget=forms.Input)
password = CharField(widget=forms.Input)
age = CharField(widget=forms.Input)
def user_add(request):
if request.method == "GET":
# 实例化MyForm()
form =MyForm()
return render(request, 'user_add.html', {"form":form})
<form method="post">
<!-- 直接显示为上面的三个input框 -->
{% for field in form %}
{{ field }}
{% endfor %}
<!-- 其中placeholder中的值位model.py中的verbose_name -->
<!-- <input type="text" placeholder="姓名" name="name"/> -->
</form>
ModelForm组件
ModelForm组件
# model.py
class UserInfo(models.Model):
name = models.CharField(verbose_name="姓名", max_length=32)
password = models.CharField(verbose_name="密码", max_length=64)
age = models.IntegerField(verbose_name="年龄")
account = models.DecimalField(verbose_name="余额", max_digits=10, decimal_places=2, default=0)
create_time = models.DateTimeField(verbose_name="入职时间")
department = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
# views.py
# 引入forms
from django import forms
# 创建自己的Form类
class My_Form(forms.ModelForm):
# 这里面也可以自己定义字段
# hobby = CharField(widget=forms.Input)
class Meta:
# 只选取数据库字段的一部分
model = models.UserInfo
# 前端想用谁,fields中就写谁
fields = ["name", "password", "age"]
def user_add(request):
if request.method == "GET":
# 实例化My_Form()
form = My_Form()
return render(request, 'user_add.html', {"form":form})
<form method="post">
<!-- 直接显示为上面的三个input框 -->
{% for field in form %}
{{ field.label }} : {{field}}
{% endfor %}
<!-- 其中placeholder中的值位model.py中的verbose_name -->
<!-- <input type="text" placeholder="姓名" name="name"/> -->
</form>
重写__str__(self)
通过modelform查询的department结果为queryset,并不是我们想要的结果,所以我们通过重写__str __方法来实现使其查询的结果为我们想要的结果
# model.py中
class Department(model.Models):
title = models.CharField(verbose_name="部门", max_length=32)
def __str__(self):
return self.title
给ModelForm生成的结果添加样式
# views.py
from django import forms
class My_Form(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ["name", "password", "age"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 给所有插件添加属性
for name, field in self.field.items();
# 如果name为password时,不添加样式
if name == "password":
continue
field.widget.attrs = {"class" : "form-control", "placeholder" : field.label}
添加用户
# views.py
def user_modelform_add(request):
# ...
form = MyForm(data = request.POST)
if form.is_valid():
# 保存到数据库
form.save()
return redirect("/user/list/")
else:
return render(request, "user_modelform_add.html", {"form":form})
<!--novalidata 关闭浏览器对提交信息的校验-->
<form method="post" novalidata>
{% for field in form %}
<div class="form-group">
{{ field.label }} : {{field}}
<span>{{field.errors.0}}</span>
</div>
<!--field.error返回的结果为list,我么只需要返回第一个错误就行-->
{% endfor %}
</form>
modelform中的验证还有很多,可以通过重写数据库已定义的属性
# views.py
from django import forms
class My_Form(forms.ModelForm):
# 这里面也可以自己定义字段
# hobby = forms.CharField(widget=forms.Input)
# age字符串长度最小为2,如果不是,则会提交时报错
age = forms.Charfield(min_length=2)
# 密码中也可以设置正则表达式 validators
class Meta:
model = models.UserInfo
fields = ["name", "password", "age"]
正则表达式
# 手机号验证1
from django import forms
from django.core.validators import RegexValidator
class YourModelForm(forms.ModelForm):
phone_number = forms.CharField(validators=[RegexValidator(
regex='^1[3456789]\d{9}$',
message='请输入有效的手机号码',
code='invalid_phone_number'
)])
# 手机号验证2
from django import forms
from django.core.exceptions import ValidationError
class YourModelForm(forms.ModelForm):
class Meta:
model = UserInfo
fields = ["name", "password", "age"]
# 定义clean方法
def clean_age(self):
# 获取传过来的age值
age = self.cleaned_data["age"]
# 判断
if length(age) > 2:
raise ValidationError("年龄超出范围")
不可重复
from django import forms
from django.core.exceptions import ValidationError
class YourModelForm(forms.ModelForm):
class Meta:
model = UserInfo
fields = ["name", "password", "age"]
# 定义clean方法
def clean_age(self):
# 获取传过来的age值
get_age = self.cleaned_data["age"]
# 判断值是否已存在
exists = UserInfo.objects.filter(age=get_age).exists()
# 判断
if exists:
raise ValidationError("您输入的值已存在")
return get_age
改报错语言
# settings.py
LANGUAGE_CODE = 'zh-hans'
自定义、全选和排除
# views.py 中
from django import forms
class MyForm(forms.ModelForm):
class Meta:
model = UserInfo
# 自定义字段/选修
# 1.fields = ["name", "password", "age"]
# 数据库中的全选
# 2.fields = "__all__"
# 排除某个字段
# 3.exclude = ["create_time"]
fields = ["name", "password", "age"]
编辑用户和提交
# urls.py
path('user_edit.html', user/<int:nid>/edit)
# views.py
def user_edit(request, nid):
# 通过id拿到对象
data = UserInfo.objects.filter(id=nid).first()
if request.method == "GET":
# 实例化的同时把对象传过来instance接收
forms = MyForm(instance=data)
return render(request, "user_edit.html", {"forms" : forms})
form = MyForm(data=request.POST, instance=data)
if form.is_valid:
# 自动添加
# form.instance.account = 10000
form.save()
return redirect("/user/list")
return render(request, "user_edit.html", {"forms":form})
用户入职时间可以不出现时分秒,所以可以把models.py中的create_time字段改为DataField
正则表达式
不可重复(不同于添加)
from django import forms
from django.core.exceptions import ValidationError
class YourModelForm(forms.ModelForm):
class Meta:
model = UserInfo
fields = ["name", "password", "age"]
# 定义clean方法
def clean_age(self):
# 获取传过来的age值
get_age = self.cleaned_data["age"]
# 判断值是否已存在
exist = UserInfo.objects.exclude(id=self.instance.pk).filter(age=get_age).exist()
# 判断
if exist:
raise ValidationError("您输入的值已存在")
可见不可修改
from django import forms
from django.core.exceptions import ValidationError
class YourModelForm(forms.ModelForm):
class Meta:
model = UserInfo
fields = ["name", "password", "age"]
# 定义clean方法
def clean_age(self):
# 获取传过来的age值
get_age = self.cleaned_data["age"]
# 判断值是否已存在
# 判断是排除自身,instance为获取到的对象,pk(primary key)
exist = UserInfo.objects.filter(age=get_age).exclude(self.instance.pk).exist()
# 判断
if exist:
raise ValidationError("您输入的值已存在")
删除
查看列表
def num_list(request):
# 这里我们也可以给查找的数据进行排序
# .order_by("-price") 价格倒序
all_data = PhoneNumber.objects.all()
return render(request, "num_list.html")
filter()
# 数字
PhoneNumber.objects.filter(id = 2) # 等于
PhoneNumber.objects.filter(id__gt = 2) # 大于
PhoneNumber.objects.filter(id__gte = 2) # 大于等于
PhoneNumber.objects.filter(id__lt = 2) # 小于
PhoneNumber.objects.filter(id__lte = 2) # 小于等于
# 字符串(典型)
PhoneNumber.objects.filter(pnumber="17676767676")
PhoneNumber.objects.filter(pnumber__startswith="158")
PhoneNumber.objects.filter(pnumber__endswith="789")
PhoneNumber.objects.filter(pnumber__contains="567 ")
# 一般方法传入filter
PhoneNumber.objects.filter(pnumber="17676767676")
# dict传入
text = {
pnumber="17676767676",
id = 1
}
PhoneNumber.objects.filter(**text)
搜索
def num_list(request):
# 定义一个空字典
dict = {}
# 获取前端传过来的value或者空值
value = request.GET.get("value", "")
# 判断是非为空
if value:
# 在dict中创建字段 pnumber_contain=value
dict["pnumber__contains"] = value
# 把dict传给filter查询数据
data = PhoneNumber.objects.filter(**dict)
# 把前端传的value再传给前端
return render(request, "num_list.html", {"data":data, "value":value})
<div style="float:right; width:300px; border: 1px solid; border-radius: 5px">
<form method="get">
<div class="input-group">
<!-- 当submit时,直接把name拼接给路径 -->
<input type="text" name="value" value="{{value}}" class="form-control" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">搜索</button>
</span>
</div>
</form>
</div>
分页
前言
# 查看第5条到第15条数据(不含第5个)
PhoneNumber.objects.all()[5:15]
封装分页类
时间选择插件
<!--首先引入插件-->
{% extends 'layout.html' %}
{% load static %}
{% block css %}
<link rel="stylesheet" href="{% static 'plugins/bootstrap-datepicker/css/bootstrap-datepicker.min.css' %}">
{% endblock %}
<!--内容-->
{% block js %}
<script rel="stylesheet" src="{% static 'plugins/bootstrap-datepicker/js/bootstrap-datepicker.js' %}"></script>
<script rel="stylesheet" src="{% static 'plugins/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js' %}"></script>
<script>
$(function () {
<这里面
$('#id_create_time').datepicker({
format: 'yyyy-mm-dd',
startDate: '0',
language: "zh-CN",
autoclose: true
});
})
</script>
{% endblock %}
在这里插入代码片