12.03

时间:2019-12-03
本文章向大家介绍12.03,主要包括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

原文地址:https://www.cnblogs.com/maqiaobin/p/11978929.html