![]()
1、前面疑点难点:
1、为什么Ajax 相关的值只能通过data 传,而用普通方法如:request.POST.get("")却不行了,是因为ContentType,此时POST里面就没有值可取,只能通过data
2、render是渲染变量到模板中,没有执行相应的action;而redirect是HTTP中的1个跳转的函数,一般会生成302状态码。
3、验证码刷新问题:
1、删除再添加代码块由于缓存机制,同一个域名不会重新加载验证码
2、域名尾缀不能加其它否则就会找不到域名
答:但,?和# 号是一个参数,可以在后面加,所以用Math.random去改变尾缀,这时候即不是完全相同的一个域名,又不影响本身域名的指向性。
4、后端向前端传值,render(request, "" {"data": data}),前端 {{ data }} 即可获得值
2、Forms组件:
- 页面初始化,生成HTML标签
- 校验用户数据(显示错误信息)
- HTML Form提交保留上次提交数据
1、小试牛刀
# 定义Form类 在新建的MyForms里
from django import forms
class EmpForm(forms.Form):
name = forms.CharField(min_length=5, label="姓名", error_messages={"required": "该字段不能为空!","min_length": "用户名太短。"})
# min_length 定义最小字符数;label 用户可见文字;erro_massages 报错信息,required 当用户输入为空并提交时提示(一般浏览器有自动做这个);min_length 当用户输入过短时;
age = forms.IntegerField(label="年龄")
salary = forms.DecimalField(max_digits=5, decimal_places=2, label="工资")
# max_digits 最大数字个数,decimal_places 小数点多少位
# 设计urls 与视图对应关系
from django.urls import path
from app01 import views
urlpatterns = [
path('add_emp/', views.add_emp),
]
# 顶级__init__里,添加
import pymysql
pymysql.install_as_MySQLdb()
# 视图函数
from app01.MyForms import EmpForm
def login(request):
if request.method == "POST":
form = EmpForm(request.POST) # 可以直接取form 值
if form.is_valid(): # 校验值跟EmpForm配置的校验类是否数值一直,多了也不报错,但是不同或位置不同就会报错
print(form.cleaned_data) # 打印查看情况,类似字典的格式
models.EmpForm.objects.create(**form.cleaned_data) # 创建数据
else:
print(form.errors)
else:
form = EmpForm() # 将用户输入内容,即使错的,也放进form表单里
return render(request, "login.html", {"form": form})
# 模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h3>添加员工</h3>
{#1、自己手动写HTML页面#}
{#<form action="" method="post">#}
{# <p>姓名:<input type="text" name="name"></p>#}
{# <p>年龄:<input type="text" name="age"></p>#}
{# <p>工资:<input type="text" name="salary"></p>#}
{# <input type="submit">#}
{#</form>#}
{#2、通过form对象的as_p方法实现,自定制性不强#}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# {{ form.as_p }}#} # 这里的名字最好跟上面的form action 不一样
{# <input type="submit">#}
{#</form>#}
{#3、手动获取form对象的字段#}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# <div>#}
{# <label for="id_{{ form.name.name }}">姓名</label>#}
{# {{ form.name }} <span>{{ form.name.errors.0 }}</span>#}
{# </div>#}
{# <div>#}
{# <label for="id_{{ form.age.name }}">年龄</label>#}
{# {{ form.age }} <span>{{ form.age.errors.0 }}</span>#}
{# </div>#}
{# <div>#}
{# <label for="id_salary">工资</label>#}
{# {{ form.salary }} <span>{{ form.salary.errors.0 }}</span>#}
{# </div>#}
{# <input type="submit">#}
{#</form>#}
{#4、用for循环展示所有字段#}
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div>
<label for="id_{{ field.name }}">{{ field.label }}</label> # lable是获取名字
{{ field }} <span>{{ field.errors.0 }}</span> # field是拿对象,多少个自动渲染多少个框
</div>
{% endfor %}
<input type="submit">
</form>
</body>
</html>
3、局部钩子和全局钩子
# 在MyForm EmpForm类下面添加
from django.core.exceptions import ValidationError
from app01 import models
# 局部钩子
def clean_name(self): # 名称不能随便起,必须要clean_类属性名称
val = self.cleaned_data.get("name") # 获取name的值
if val.isdigit():
raise ValidationError("用户名不能全是数字。")
elif models.Emp.objects.filter(name=val): # 校验数据库种的值
raise ValidationError("用户名已存在。")
else:
return val
def clean(self):
salary = self.cleaned_data.get("salary")
r_salary = self.cleaned_data.get("r_salary") # 两个工资的输入值进行校验
if salary != r_salary:
raise ValidationError("工资输入有误。")
else:
return self.cleaned_data
# 视图函数
<form action="" method="post" novalidate>
{% csrf_token %}
<div>
<label for="id_{{ form.name.name }}">姓名</label>
{{ form.name }} <span>{{ form.name.errors.0 }}</span>
</div>
<div>
<label for="id_{{ form.age.name }}">年龄</label>
{{ form.age }} <span>{{ form.age.errors.0 }}</span>
</div>
<div>
<label for="id_salary">工资</label>
{{ form.salary }} <span>{{ form.salary.errors.0 }}{{ clear_errors.0 }}</span> # views全局钩子是一种返回all 对象块的形式,要以0去单独获取
</div>
<div>
<label for="id_r_salary">请再输入工资</label>
{{ form.r_salary }} <span>{{ form.r_salary.errors.0 }}{{ clear_errors.0 }}</span>
</div>
<input type="submit">
</form>
# 视图函数种
def login(request):
if request.method == "POST":
# data = request.POST.get()
form = EmpForm(request.POST)
if form.is_valid():
print(1111,form.cleaned_data)
# models.Emp.objects.create(**form.cleaned_data)
emp_obj = models.Emp.objects.filter(name=form.cleaned_data.get('name'),
age=form.cleaned_data.get('age'),
salary=form.cleaned_data.get('salary')).first()
if emp_obj:
request.session['is_login'] = True
path = request.GET.get('next') or "/index/"
return redirect(path)
else:
clear_errors = form.errors.get("__all__") # 获取全局钩子错误信息
return render(request, "login.html", {"form": form, "clear_errors": clear_errors})
else:
form = EmpForm()
return render(request, "login.html", {"form": form})
4、用户认证组件
1、auth模块
from django.contrib import auth
django.contrib.auth中提供了许多方法,这里主要介绍其中的三个:
2、Navicat Premium 里有一个存在的auth_user 已配置好可以使用
# Terminal
python manage.py createsuperuser # 回车然后就会让你输入姓名邮箱和命名,超级用户是一定要输入邮箱的
3、方法一:authenticate(username=user, password=pwd) # 过滤合法用户。有则返回该对象,无,返回Nonedef auth_login(request): # 登陆用户
if request.method == "POST":
user = request.POST.get("user")
pwd = request.POST.get("pwd")
user_obj = auth.authenticate(username=user, password=pwd) # 过滤合法用户。有则返回该对象,无,返回None
print(user_obj, type(user_obj))
print(user_obj)
# print(user_obj.username)
# print(user_obj.email)
if user_obj:
auth.login(request, user_obj) # 1.设置session值,request.user = user_obj
path = request.GET.get('next') or "/index/"
# 是它或者另外一个,这里的next是因为自制装饰器时,跳转到login页面时写为"/login/?next=%s" % path
path 是通过request.path获取的
return redirect(path)
return render(request,"login1.html")
def auth_logout(request):
# 注销用户
auth.logout(request) # 1.清楚session信息 2.把request.user 重新赋值为匿名用户。
return redirect("/auth_login/")
4、方法二:django已经为我们设计好了一个用于此种情况的装饰器:login_required()
# setting 里配置这个,不然默认的是跳转到 '/accounts/login/'
LOGIN_URL = '/auth_login/'
5、方法三:创建用户
# 视图函数中
def index(request):
user = "alexjsdsb"
pwd = "dsb945"
# User.objects.create(username=user, password=pwd) # 常规情况下,这样创建用户。密码不安全。明文。
# user_obj = User.objects.create_user(username=user, password=pwd) # 创建普通用户
user_obj = User.objects.create_superuser(username=user, password=pwd, email="alex@163.com") # 创建超级用户。
print(1111, user_obj)
return HttpResponse("这是主页。。。")
修改密码等更多内容尽在