zoukankan      html  css  js  c++  java
  • 12.03

    多对多三种创建方式

    全自动

    class Book(models.Model):
        title  = models.CharField(max_length=32)
        authors = models.ManyToManyField(to='Authors')
    
    class Authors(models.Model):
        name = model.CharField(max_length=32)
    

    好处:

    orm自动创建第三张表

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

    1. add
    2. remove
    3. set
    4. clear

    坏处:

    自动创建的第三张表无法修改字段,表的扩展性差

    纯手撸

    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等方法

    半自动

    推荐使用的创建方式

    class Book(models.Model):
        title = models.CharField(max_length=32)
        authors = models.ManyToMany(to='Authors',through='Book2Author',throuth_fields=("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跨表查询

    坏处:

    不支持add等方法

    forms 校验性组件

    form组件的常用字段

    initial:初始值,input框里面的初始值
    
    error_messages:重写错误信息
    
    password:密文
    
    radioselect:单radio值为字符串
    
    label:input对应的提示信息
    
    required:默认为True控制字段是否必填
    
    widget:给input框设置样式及属性
    

    form组件的主要功能:

    • 生成页面可用的HTML标签
    • 对用户提交的数据金进行校验
    • 保留上次输入的内容

    使用forms组件的前提需要导入forms模块

    再写一个类:

    class MyForm(forms.Form):
        username=forms.CharField(max_length=8,min_length=3)
        password = forms.Charfield(max_length=8,min_length=3)
        email = forms.EmailField()
    

    校验数据

    # 给写好的类传字典数据
    form_obj = views.MyForm({'username':'qqq','password':'123','email':'123@qq.com'})
    
    # 查看校验的数据是否合法
    form_obj.is_valid() # 只有当数据全部符合校验规则,结果才是True
    
    # 查看不符合规则的字段以及错误的理由
    form_obj.errors
    
    # 查看符合校验规则的数据
    form_obj.cleaned_data
    

    注意:forms组件中,定义的字段默认都是必须传值的,不能少传,但是多传不会有任何影响

    渲染标签

    forms组件只会渲染获取用户输入的标签,不会渲染提交按钮

    • forms组件渲染标签方式1:

      {{form_obj.as_p}} <!--自动渲染所有input框-->
      {{form_obj.as_ul}}
      {{form_obj.as_table}}
      

      封装程度太高,不推荐使用

    • forms组件渲染标签方式2:

      {{ form_obj.username.label}}{{form_obj.username}}
      {{ form_obj.password.label}}{{form_obj.password}}
      {{ form_obj.email.label}}{{form_obj.email}}
      

      写起来麻烦,不推荐使用

    • forms组件渲染标签方法3

      {% 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>
    

    内置的校验器

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

    钩子函数

    局部钩子

    在form类中定义clean_字段名()方法,实现对特定字段进行校验

        def clean_username(self):
            username = self.cleaned_data.get('username')
            if '666' in username:
                # 给username所对应的框展示错误信息
                # self.add_error('username','光喊666是不行的')
                raise ValidationError('到底对不对啊')
            # 将username数据返回
            return username
    

    全局钩子

    在form类中定义clean()方法,就能实现对字段进行全局校验

        def clean(self):
            password = self.cleaned_data.get("password")
            confirm_password = self.cleaned_data.get("confirm_password")
            if not password == confirm_password:
                self.add_error('confirm_password', '两次密码不一致')
            # 将全局的数据返回
            return self.cleaned_data
    
  • 相关阅读:
    CS224n, lec 10, NMT & Seq2Seq Attn
    CS231n笔记 Lecture 11, Detection and Segmentation
    CS231n笔记 Lecture 10, Recurrent Neural Networks
    CS231n笔记 Lecture 9, CNN Architectures
    CS231n笔记 Lecture 8, Deep Learning Software
    CS231n笔记 Lecture 7, Training Neural Networks, Part 2
    pytorch坑点排雷
    Sorry, Ubuntu 17.10 has experienced an internal error
    VSCode配置python插件
    tmux配置与使用
  • 原文地址:https://www.cnblogs.com/maqiaobin/p/11978929.html
Copyright © 2011-2022 走看看