fifty-three Forms组件/用户认证组件

 

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("这是主页。。。")

  修改密码等更多内容尽在

posted @ 2019-03-25 17:48  pythonernoob  阅读(147)  评论(0)    收藏  举报