Django多对多关系建立及Form组件

目录

  • Django多对多关系

    • 1.创建方式一全自动
    • 2.创建方式二纯手撸
    • 3.半自动(推荐使用)
  • forms校验组件
    • 使用forms组件实现注册功能
    • form常用字段和插件
    • 数据校验
    • 钩子函数 HOOK

Django多对多关系

1.创建方式一全自动

class Book(models.Model):
        title = models.CharField(max_length=32)
        # 多对多关系字段
        authors = models.ManyToManyField(to='Authors')

class Authors(models.Model):
        name = models.CharField(max_length=32)

好处:至始至终你都没有操作第三张表 全部都是由orm自动帮你创建的

字段内置了四个操作第三张表的方法

add
remove
set
clear

不足:自动创建的第三张表无法扩展个修改字段 表的扩展性较差

2.创建方式二纯手撸

class Book(models.Model):
        title = models.CharField(max_length=32)

class Authors(models.Model):
        name = models.CharField(max_length=32)

class Book2Authors(models.Model):
        book = models.ForeignKey(to="Book")
        author = models.ForeignKey(to="Authors")
        create_time = models.DateField(auto_now_add = True)

好处:第三张表中字段个数和字段名称全都可以自己定义

不足:不再支持orm跨表查询 不再由正反向的概念

add
remove
set
clear

3.半自动(推荐使用)

class Book(models.Model):
        title = models.CharField(max_length=32)
        # 多对多关系字段
        authors = models.ManyToManyField(to='Authors',through='Book2Author',through_fields=("book","authors"))
        # 不通过orm创建,而是通过第三张表中->through='Book2Author'的through_fields=("authors","book"),authors和book字段
        #     through_fields=("authors","book")中的"authors"字段,可以这样记:在哪张表里面该字段就放在最前面

        """
        当你的ManyToManyField只有一个参数to的情况下 orm会自动帮你创建第三张表
        如果你加了through和through_fields那么orm就不会自动帮你创建第三张表 但是它会在内部帮你维护关系 让你能够继续使用orm的跨表查询
        through  自己指定第三张关系表
        through_fields  自己指定第三张关系表中 到底哪两个字段维护者表与表之间的多对多关系
        """

class Authors(models.Model):
        name = models.CharField(max_length=32)
        # 多对多关系字段  等价
        books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=("authors","book"))

class Book2Author(models.Model):
    book = models.ForeignKey(to='Book')
        authors = models.ForeignKey(to='Authors')
  • 不通过orm创建,而是通过第三张表中->through=‘Book2Author‘的through_fields=("authors","book"),authors和book字段
  • through_fields=("authors","book")中的"authors"字段,可以这样记:在哪张表里面该字段就放在最前面
  • 该表可以有任意多的外键字段
  • 可以扩展任意的字段

好处:可以任意的添加和修改第三张表中的字段
并且支持orm跨表查询
不足:不支持

add
remove
set
clear

forms校验组件

forms组件
    前戏
        需求:
            1.写一个注册页面 获取用户输入的用户名和密码
            提交到后端之后 后端需要对用户名和密码做校验
            用户名里面不能含有葫芦娃
            密码不能少于三位
            如果不符合 展示对应的错误信息

        forms组件   能够做的事情
        1.手动书写html代码获取用户输入              >> >> >>    渲染标签
        2.将数据转递给后端做数据校验                >> >> >>    校验数据
        3.如果数据有错误 你还展示了错误信息         >> >> >>    展示信息

使用forms组件的前提是 你需要提前写一个类

from django import forms

class MyForm(forms.Form):
    # username字段 最少三位 最多八位
    username = forms.CharField(max_length=8,min_length=3)
    # password字段 最少三位  最多八位
    password = forms.CharField(max_length=8,min_length=3)
    # email字段 必须是邮箱格式
    email = forms.EmailField()

校验数据
    # 1.给写好的类 传字典数据(待校验的数据)
    form_obj = views.MyForm({'username':'jason','password':'12','email':'123'})
    # 2.如何查看校验的数据是否合法
    form_obj.is_valid()
    False  # 只有当你的数据全部符合校验规则的情况下 结果才是True 否则都为False
    # 3.如何查看不符合规则的字段及错误的理由
    form_obj.errors
    {
    'password': ['Ensure this value has at least 3 characters (it has 2).'],
    'email': ['Enter a valid email address.']
    }
    # 4.如何查看符合校验规则的数据
    form_obj.cleaned_data
    {'username': 'jason'}
    # 5.forms组件中 定义的字段默认都是必须传值的  不能少传
    form_obj = views.MyForm({'username':'jason','password':'12345'})
    form_obj.is_valid()
    False
    form_obj.errors
    {'email': ['This field is required.']}
    # 6.forms组件只会校验forms类中定义的字段  如果你多传了 不会有任何影响
    form_obj = views.MyForm({'username':'jason','password':'12345','email':'[email protected]','xxx':'嘿嘿嘿'})
    form_obj.is_valid()
    True

渲染标签
    forms组件只会帮你渲染获取用户输入的标签 不会帮你渲染提交按钮 需要你自己手动添加

    <p>forms组件渲染标签方式1:封装程度态高 不推荐使用 但是可以用在本地测试</p>
    {{ form_obj.as_p }}  <!--自动渲染所有input框  -->
    {{ form_obj.as_ul }}
    {{ form_obj.as_table }}
    <p>forms组件渲染标签方式2:不推荐使用 写起来太烦了</p>
    {{ form_obj.username.label }}{{ form_obj.username }}
    {{ form_obj.username.label }}{{ form_obj.password }}
    {{ form_obj.username.label }}{{ form_obj.email }}
    <p>forms组件渲染标签方式3:推荐使用 </p>
    {% for form in form_obj %}
    <p>{{ form.label }}{{ form }}</p>  <!--form 等价于你方式2中的对象点字段名-->
    {% endfor %}

展示信息
<p>forms组件渲染标签方式3:推荐使用 </p>
<form action="" method="post" novalidate>
    {% for forms in form_obj %}
    <p>
        {{ forms.label }}{{ forms }}
        <span>{{ forms.errors.0 }}</span>
    </p>  <!--form 等价于你方式2中的对象点字段名-->
    {% endfor %}
    <input type="submit">
</form>

使用forms组件实现注册功能

先定义好一个ReGForm类:

from django import forms

# 按照Django form组件的要求自己写一个类
class RegForm(forms.Form):
    name = forms.CharField(label="用户名")
    pwd = forms.CharField(label="密码")

再写一个视图函数

# 使用form组件实现注册方式
def register2(request):
    form_obj = RegForm()
    if request.method == "POST":
        # 实例化form对象的时候,把post提交过来的数据直接传进去
        form_obj = RegForm(request.POST)
        # 调用form_obj校验数据的方法
        if form_obj.is_valid():
            return HttpResponse("注册成功")
    return render(request, "register2.html", {"form_obj": form_obj})

login.htmll

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册2</title>
</head>
<body>
    <form action="/reg2/" method="post" novalidate autocomplete="off">
        {% csrf_token %}
        <div>
            <label for="{{ form_obj.name.id_for_label }}">{{ form_obj.name.label }}</label>
            {{ form_obj.name }} {{ form_obj.name.errors.0 }}
        </div>
        <div>
            <label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label>
            {{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }}
        </div>
        <div>
            <input type="submit" class="btn btn-success" value="注册">
        </div>
    </form>
</body>
</html>

看网页效果发现也验证了form的功能:

前端页面是form类的对象生成的——>生成HTML标签功能

当用户名和密码输入为空或输错之后 页面都会提示——>用户提交校验功能

当用户输错之后再次输入上次的内容还保留在input框中——>保留上次输入内容

form常用字段和插件

initial

初始值,input框里面的初始值

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三"  # 设置默认值
    )
    pwd = forms.CharField(min_length=6, label="密码")

error_messages

重写错误信息

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    )
    pwd = forms.CharField(min_length=6, label="密码")
password
class LoginForm(forms.Form):
    ...
    pwd = forms.CharField(
        min_length=6,
        label="密码",
        widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
    )

radioSelect

单radio值为字符串

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    )
    pwd = forms.CharField(min_length=6, label="密码")
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        initial=3,
        widget=forms.widgets.RadioSelect()
    )

单选select

class LoginForm(forms.Form):
    ...
    hobby = forms.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select()
    )

多选select

class LoginForm(forms.Form):
    ...
    hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )

单选checkbox

class LoginForm(forms.Form):
    ...
    keep = forms.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )

多选checkbox

class LoginForm(forms.Form):
    ...
    hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )

数据校验

数据的校验通常前后端都必须有
但是前端的校验可有可无 并且弱不禁风
后端的校验必须要有 并且必须非常的全面
如何告诉浏览器不做校验 form表单中加一个novalidate参数即可

<form action="" method="post" novalidate>

内置的校验器

from django.core.validators import RegexValidator
                validators=[
                            RegexValidator(r'^[0-9]+$', '请输入数字'),
                            RegexValidator(r'^159[0-9]+$', '数字必须以159开头'),
                        ]

钩子函数 HOOK

当你觉得上面的所有的校验还不能够满足你的需求 你可以考虑使用钩子函数
是一个函数 函数体内你可以写任意的校验代码

局部钩子

你想校验单个字段

全局钩子

你想校验多个字段

Hook函数实例

原文地址:https://www.cnblogs.com/nangec/p/11988508.html

时间: 2024-10-28 07:38:34

Django多对多关系建立及Form组件的相关文章

Django 批量插入数据、自定义分页器、多表关系的建立及Form组件(待更新。。。)

目  录 django批量出入数据 自定义分页器 创建多对多表关系的建立 form组件 form组件钩子函数 一.django批量出入数据 视图函数: from app01 import models # 向表中插入1000条数据 def index(request): # 方式1: # for i in range(1000): # models.Book.objects.create(title='第%s本书'%i) # book_Queryset = models.Book.objects

Django 【第十一篇】Form组件基础

一.model常用操作 1.13个API查询:all,filter,get ,values,values_list,distinct,order_by ,reverse , exclude(排除),count,first,last,esits(判断是否存在) 需要掌握的all.values.values_list的区别 all:打印的是一个QuerySet集合,一个列表里面放的对象 values :是一个字典形式 values_list:是一个元组形式 all的性能是最低的 2.only和def

Django 多对多关系的增删改查

目录 Django多对多数据增删改查 1.表结构及基本方法 2.查 3.增 4.改 Django多对多数据增删改查 1.表结构及基本方法 1.表结构 # models.py class Book(models.Model): author = models.ManyToMany(to='author', relate_name='author') """ ...字段 """ class author(models.Model): "&q

Django 【第十三篇】Form组件归类

一.Form类 创建Form类时,主要涉及到 [字段] 和 [插件],字段用于对用户请求数据的验证,插件用于自动生成HTML; 1.Django内置字段如下: Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label标签或显示内容 initial=None, 初始值 help_text='', 帮助信息(在标签旁边显示) error_messages=None, 错误信息 {'required': '不能为空',

django 学习-10 Django多对多关系模型

1.vim blog/models.py class   Author(models.Model): name = models.CharField(max_length=30) def unicode(self): return self.name class Book(models.Model): name = models.CharField(max_length=30) authors = models.ManyToMany(Author) def unicode(self): retu

六、hibernate表与表之间的关系(多对多关系)

多对多关系 创建实体类和对应映射文件 Student.java 1 package com.qf.entity; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 public class Student { 7 8 private Long sid; 9 private String sname; 10 //一个学生可以有很多个老师 11 private Set<Teacher> teachs = new HashSet<

Django多对多的增删改查

Django 多对多 关系 多对多,本意就是多个一对多的关系 定义多对多 ManyToManyField 字段 from django.db import models # 学生类 class Student(models.Model): name = models.CharField(max_length=32) # 老师类 class Teacher(models.Model): name = models.CharField(max_length=32) students = models

form组件使用、常用字段、字段参数、自定义校验规则:

views: from django.shortcuts import render,HttpResponse # Create your views here.def reg(request): if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd") if len(pwd) <= 6: return render(

Python Django 多对多三种创建方式 form组件 cookie和session

一 表中多对多关系三种创建方式 以Book表和Author表多对多关系例 1.第一种方式:全自动(推荐使用):models.ManyToManyField(to='类名') 优点:不需要你手动创建第三张表 缺点:第三张表不是你手动创建的,字段是固定的无法拓展 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_place