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
    
  • 相关阅读:
    SQL Server中生成指定长度的流水号
    属性与字段的区别
    Tomcat启动时的异常~!!!
    全面认识验证身份的数字证书
    MyEclipse 5.5 开发 Spring + Struts + Hibernate 的详解视频(长1.5小时)
    resin是什么?是Application Server吗?是WebLogic,Websphere他们的竞争对手吗?
    发现一个HTML得秘密
    用 MyEclipse 开发的最简单的 Spring 例子
    什么是WebSphere?WebSphere是干什么用的?中间件是什么意思?
    简单jsp+servlet实例
  • 原文地址:https://www.cnblogs.com/maqiaobin/p/11978929.html
Copyright © 2011-2022 走看看