说重点!其他大同小异
特殊数据处理
数据展示
time = models.DateTimeField(verbose_name="入职时间")
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
gender_choices = ((1, "男"), (2, "女"))
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
.DateTime类型数据
2021-09-29 00:00:00.
转换成字符串形式
ulist[0].time.strftime(”%Y~%m~%d“)
html中
{{ i.time|date:"Y-m-d H:i:s"}}
.ForeignKey 外联表
userinfo表中列为depart_id 不过
ulist[0].depart_id # 部门id1/2
ulist[0].depart, #Department object对象
ulist[0].depart.title #obj对象的titile属性即为部门名字
html中
{{ i.depart.title }}
_choices 性别
ulist[0].get_gender_display() #找到对应值
html中
{{ i.get_gender_display }}
完整ulist.html代码.
{% extends 'moban.html' %}
{% block mbname %}
<div class="container">
<div class="bs-example" data-example-id="panel-without-body-with-table">
<div class="panel panel-default">
<div class="panel-heading"><span class="glyphicon glyphicon-list" aria-hidden="true"></span> 部门列表
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>名字</th>
<th>年龄</th>
<th>余额</th>
<th>入职时间</th>
<th>性别</th>
<th>部门</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for i in ulist %}
<tr>
<td>{{ i.id }}</td>
<td>{{ i.name }}</td>
<td>{{ i.age }}</td>
<td>{{ i.account }}</td>
<td>{{ i.time|date:"Y-m-d "}}</td>
<td>{{ i.get_gender_display }}</td>
<td>{{ i.depart.title }}</td>
<td>
<a class="btn btn-primary btn-xs" href="/uedit/{{ i.id }}">编辑</a>
<a class="btn btn-danger btn-xs" href="/udel/?delid={{ i.id }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
数据增加(传统)
性别和部门下拉框
构造的字典contex,当参数传递:
{ ‘xbchoices’: ((1, ‘男’), (2, ‘女’)) ;
‘bmlist’:obj }
所以在html中能直接使用xbchoices,bmlist两个参数
def uadd(request):
# 增加用户s
contex = {
'xbchoices': models.Userinfo.gender_choices, # = ((1, '男'), (2, '女'))
'bmlist': models.Department.objects.all() #Department object 对象
}
return render(request, 'uadd.html', contex)
uadd.html代码
<select class="form-control">
{% for i in xbchoices %}
<option value="{{ i.0 }}">{{ i.1 }}</option>
{% endfor %}
</select>
....
....
<select class="form-control">
{% for i in bmlist %}
<option value="{{ i.id }}">{{ i.title }}</option>
{% endfor %}
</select>
...
带样式
<div class="form-group">
<label class="col-sm-2 control-label">性别</label>
<div class="col-sm-8">
<select class="form-control">
{% for i in xbchoices %}
<option value="{{ i.0 }}">{{ i.1 }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">部门</label>
<div class="col-sm-8">
<select class="form-control">
{% for i in bmlist %}
<option value="{{ i.id }}">{{ i.title }}</option>
{% endfor %}
</select>
</div>
</div>
选择后前端将value的值传递到后端来
可选择的时间
引入datetimepicker插件
导入需要的html中 (uadd/uedit)
{% extends 'moban.html' %}
{% load static %}
{% block css %}
<link rel="stylesheet" href="{% static 'jquery/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.min.css' %}">
{% endblock %}
{% block js %}
<script src="{% static 'jquery/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.min.js' %}"></script>
<script src="{% static 'jquery/bootstrap-datetimepicker-master/locale/bootstrap-datetimepicker.zh-CN.js' %}"></script>
<script type="text/javascript">
$(function () {
//当容器加载完成,对容器调用工具函数
$("#id_time").datetimepicker({
language: 'zh-CN', //语言
format: 'yyyy-mm-dd',//日期的格式
minView: 'month', //可以选择的最小视图
initialDate: new Date(),//初始化显示的日期
autoclose: true,//设置选择完日期或者时间之后,日否自动关闭日历
todayBtn: true,//设置自动显示为今天
clearBtn: false//设置是否清空按钮,默认为false
});
});
</script>
{% endblock %}
效果
Django组件
注意导入时
from django import forms
而from django.forms import forms没什么用,用不好报错
- Form组件(简便)
- ModelForm组件(最简便)
Form
form使用
定义一个类myform 继承Form
字段名 = forms.CharField(widget=forms.Input) 生成charinput标签
视图函数:
实例化myform对象fff
fff携带了所有生成标签的信息
return 给html里面生成框
from django import forms
class MyForm(forms.Form):
user = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
pwd = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control'}))
email = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
def user_add(request):
if request.method == "GET":
fff = MyForm()
return render(request, "user_add.html", {"form": fff})
另外
在视图函数中
form = LoginForm(request.POST)
if form.is_valid() 之后
form.cleaned_data获得用户输入的内容【字典格式】
报错
AttributeError: ‘LoginForm’ object has no attribute ‘cleaned_data’
原因
For some reason, you’re re-instantiating the form after you check is_valid(). Forms only get a cleaned_data attribute when is_valid() has been called, and you haven’t called it on this new, second instance.
表单只有在调用了is_valid()时才获得cleaned_data属性
user_add.html
<form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
</form>
也可以不指定,自动生成全部
<form method="post">
{% for field in form %}
{{ field }}
{% endfor %}
</form>
初识 ModelForm
补充:models.py
from django.db import models
# Create your models here.
class Department(models.ModelForm):
"""部门表"""
title = models.CharField(max_length=32, verbose_name='标题')
class UserInfo(models.ModelForm):
"""员工表"""
name = models.CharField(max_length=16, verbose_name="姓名")
password = models.CharField(max_length=64, verbose_name="密码")
age = models.IntegerField(verbose_name="年龄")
account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
create_time = models.DateTimeField(verbose_name="入职时间")
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE, verbose_name="部门")
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(choices=gender_choices,verbose_name="性别")
views.py
创建类(MyForm)继承ModelForm类
from django import forms
class MyForm(forms.ModelForm):
xxx= form.CharField(x=forms.xx)
class Meta:
field = ["name", "password", "age","xxx"]
def user_add(request):
if request.method == "GET":
form = MyForm()
return render(request, "user_add.html", {"form": form})
ModelForm!!
详解:modelform逐字笔记
在视图函数中
form = LoginForm(request.POST)
if form.is_valid() 之后
form.cleaned_data获得用户输入的内容【字典格式】
另外
obj =models.Admin.objects.filter(id=edid).first()
form = AdminModelForm(instance=obj)
实例化出的form对象的输入框中,有默认内容,为obj对象所携带的哪一行的数据
增加员工
views.py
from django import forms
class Umodelform(forms.ModelForm):
# 用户名最少三位 ,设置列的verbose_name 为username,label会覆盖掉之前在models。py中的设置
name = forms.CharField(min_length=3, label="username")
class Meta: # 关键字Meta model,不一样会报错
model = models.Userinfo
# fields = ["name", "age", "time"] #可以选择那一列进行填写
fields = '__all__'
# 密码隐藏..., 手动添加属性到attrs中,
widgets = {
"password": forms.PasswordInput(attrs={'type': "password"})
}
# 重写子类方法,父类框架的方法先执行,再执行子类
# 给所有输入框增加样式class
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs = {"class": "form-control", "placeholder": field.label}
def uadd(request):
# 增加用户
if request.method == "GET":
# 生成一个Umodelform()类的对象
form = Umodelform()
return render(request, 'uadd.html', {'form': form})
# request.POST包含用户提交所有数据
form = Umodelform(data=request.POST)
# Umodelform取fields中字段来进行校验
if form.is_valid():
# 拿到输入的字段 {'name': 'django', 'password': '123', 'age': 29, 'account': Decimal('333'),
# 'time': datetime.datetime(2011, 11, 11, 0, 0, tzinfo=<UTC>),'depart': <Department: 技术部>, 'gender': 1}
# print(form.cleaned_data)
# 自动保存到数据库
form.save()
return redirect("/uadd")
# 这个地方放的form 有原来用户提交的数据,还有错误信息
# print(form.errors)
return render(request, 'uadd.html', {'form': form})
uadd.html
orm class="form-horizontal" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{# field.label为数据在models.py中定义的verbose_name属性值#}
<label class="col-sm-2 control-label">{{ field.label }}: </label>
<div class="col-sm-8">
{{ field }}
{{ field.errors.0 }}
{# 只要第一个错误信息#}
</div>
</div>
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
models.py
class Department(models.Model):
...
# 使用了就把对象变成字符串
def __str__(self):
return self.title
提示错误调中文
setings.py 中
页面展示
错了也能进行修改再提交
modelform&bootsrap
ModelForm 可以帮助我们生成HTML标签
class UserModelForm(forms.ModelForm):
name=forms.CharField(max_length=3,label="用户名")
class Meta:
model = models.Userinfo
fields = ["name", "password"]
{{ form.name }}
{{ form.password}}…
都为无样式的input框
修改样式:
定义插件
方法一:
class UserModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = [“name”, “password”,]
widgets = {
“name”: forms.TextInput(attrs={“class”: “form-control”}),
“password”: forms.PasswordInput(attrs={“class”: “form-control”}),
“age”: forms.TextInput(attrs={“class”: “form-control”}),
}
方法二:
class UserModelForm(forms.ModelForm):
name = forms.CharField(
min_length=3,
label=“用户名”,
widget=forms.TextInput(attrs={“class”: “form-control”})
)
class Meta:
model = models.UserInfo
fields = [“name”, “password”,]
方法三:重新定义init方法
# 方法三:重写子类方法,父类框架的方法先执行,再执行子类
# 重新定义init方法,批量设置,循环ModelForm所有字段 给所有输入框增加样式class
# 原来的会被覆盖掉
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
经典错误:
在类型text的input框中加属性,改类型为password
widget=forms.TextInput(attrs={“type”: “password”})
新建文件app /uinit/bsmf.py
重新init方法
bsmf.py
# author : Sun; time : 2023/2/8 20:01;
from django import forms
class BootStrapModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环ModelForm中的所有字段,给每个字段的插件设置
for _, field in self.fields.items():
# 字段中有属性,保留原来的属性,没有属性,才增加
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
else:
field.widget.attrs = {
"class": "form-control",
}
之后需要modelform使用bootstrap样式,直接继承不需要重写init方法
删除和编辑员工
urlss.py
from django.contrib import admin
from django.urls import path
from bm01 import views
urlpatterns = [
# path('admin/', admin.site.urls),
# 部门管理
path('dlist/', views.dlist),
path('dadd/', views.dadd),
path('ddel/', views.ddel),
path('dedit/<int:edid>', views.dedit),
# 员工管理
path('ulist/', views.ulist),
path('uadd/', views.uadd),
path('uedit/<int:edid>', views.uedit),
# 访问时 url= .../?nid=3 为get请求的参数在url中
# 需要request.GET.get('nid')获得
path('udel/', views.udel),
# 访问时 url= .../3 直接作为参数写在url中
# 所以def dedit()参数需要写edid,函数内直接使用
]
views.py
def uedit(request, edid):
# 编辑用户
u_obj = models.Userinfo.objects.filter(id=edid).first()
if request.method == "GET":
edform = Umodelform(instance=u_obj)
return render(request, 'uedit.html', {"form": edform})
edform = Umodelform(data=request.POST,instance=u_obj)
if edform.is_valid():
'''
#默认保存的用户输入的值
#添加用户输入之外的值可以写
form.instance.字段名字 = 字段值
'''
edform.save()
return redirect("/ulist/")
return render(request, 'uedit.html', {"form": edform})
def udel(request):
# 删除部门
nid = request.GET.get('delid')
print(nid)
models.Userinfo.objects.filter(id=nid).delete()
return redirect("/ulist/")
udeit.html
{% extends 'moban.html' %}
{% block mbname %}
<div>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">员工编辑</h3>
</div>
<div class="panel-body">
<div class="container">
<form class="form-horizontal" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label class="col-sm-2 control-label">{{ field.label }}: </label>
<div class="col-sm-8">
{{ field }}
</div>
</div>
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}