码迷,mamicode.com
首页 > 其他好文 > 详细

第八章(5)

时间:2018-07-22 17:08:43      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:ctime   apt   err   nts   gen   nes   get   帮助信息   eric   

  1. 元信息
  2. 多表关系
  3. 反向查找
  4. ORM操作
  5. 进阶操作
  6. 其它操作
  7. 高效率关联表
  8. models自带验证
  9. models内置钩子
  10. from,choices
  11. Form类
  12. From内置钩子验证
  13. obj.is_valid()错误信息

1,元信息

class UserInfo(models.Model):
        nid = models.AutoField(primary_key=True)
        username = models.CharField(max_length=32)
        class Meta:
            # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
            db_table = "table_name"


# 联合索引
            index_together = [
                ("pub_date", "deadline"),
            ]


# 联合唯一索引
            unique_together = (("driver", "restaurant"),)

            # admin中显示的表名称
            verbose_name

            # verbose_name加s
            verbose_name_plural


#最前缀的模式
			select * from where name=‘xxx‘
			select * from where name=‘xxx‘ and email=‘xx‘
			select * from where email=‘xx‘ 无法命中
			
			unique_together = (("driver","restaurant"),)

https://www.cnblogs.com/wupeiqi/articles/6216618.html

2,多表关系

ForeignKey(ForeignObject) # ForeignObject(RelatedField)
        to,                         # 要进行关联的表名
        to_field=None,              # 要关联的表中的字段名称
        on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为
                                        - models.CASCADE,删除关联数据,与之关联也删除
                                        - models.DO_NOTHING,删除关联数据,引发错误IntegrityError
                                        - models.PROTECT,删除关联数据,引发错误ProtectedError
                                        - models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
                                        - models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
                                        - models.SET,删除关联数据,
                                                      a. 与之关联的值设置为指定值,设置:models.SET(值)
                                                      b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

                                                        def func():
                                                            return 10

                                                        class MyModel(models.Model):
                                                            user = models.ForeignKey(
                                                                to="User",
                                                                to_field="id"
                                                                on_delete=models.SET(func),)
																
																
        related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
        related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values(‘表名__字段名‘)
        limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
                                    # 如:
                                            - limit_choices_to={‘nid__gt‘: 5}
                                            - limit_choices_to=lambda : {‘nid__gt‘: 5}

                                            from django.db.models import Q
                                            - limit_choices_to=Q(nid__gt=10)
                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption=‘root‘)
											
											
        db_constraint=True          # 是否在数据库中创建外键约束
        parent_link=False           # 在Admin中是否显示关联数据


    OneToOneField(ForeignKey)
        to,                         # 要进行关联的表名
        to_field=None               # 要关联的表中的字段名称
        on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为

                                    ###### 对于一对一 ######
                                    # 1. 一对一其实就是 一对多 + 唯一索引
                                    # 2.当两个类之间有继承关系时,默认会创建一个一对一字段
                                    # 如下会在A表中额外增加一个c_ptr_id列且唯一:
                                            class C(models.Model):
                                                nid = models.AutoField(primary_key=True)
                                                part = models.CharField(max_length=12)

                                            class A(C):
                                                id = models.AutoField(primary_key=True)
                                                code = models.CharField(max_length=1)

    ManyToManyField(RelatedField)
        to,                         # 要进行关联的表名
        related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
        related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values(‘表名__字段名‘)
        limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
                                    # 如:
                                            - limit_choices_to={‘nid__gt‘: 5}
                                            - limit_choices_to=lambda : {‘nid__gt‘: 5}

                                            from django.db.models import Q
                                            - limit_choices_to=Q(nid__gt=10)
                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption=‘root‘)
											
											
        symmetrical=None,           # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
                                    # 做如下操作时,不同的symmetrical会有不同的可选字段
                                        models.BB.objects.filter(...)

                                        # 可选字段有:code, id, m1
                                            class BB(models.Model):

                                            code = models.CharField(max_length=12)
                                            m1 = models.ManyToManyField(‘self‘,symmetrical=True)

                                        # 可选字段有: bb, code, id, m1
                                            class BB(models.Model):

                                            code = models.CharField(max_length=12)
                                            m1 = models.ManyToManyField(‘self‘,symmetrical=False)

        through=None,               # 自定义第三张表时,使用字段用于指定关系表
        through_fields=None,        # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
                                        from django.db import models

                                        class Person(models.Model):
                                            name = models.CharField(max_length=50)

                                        class Group(models.Model):
                                            name = models.CharField(max_length=128)
                                            members = models.ManyToManyField(
                                                Person,
                                                through=‘Membership‘,
                                                through_fields=(‘group‘, ‘person‘),
                                            )

                                        class Membership(models.Model):
                                            group = models.ForeignKey(Group, on_delete=models.CASCADE)
                                            person = models.ForeignKey(Person, on_delete=models.CASCADE)
                                            inviter = models.ForeignKey(
                                                Person,
                                                on_delete=models.CASCADE,
                                                related_name="membership_invites",
                                            )
                                            invite_reason = models.CharField(max_length=64)
        db_constraint=True,         # 是否在数据库中创建外键约束
        db_table=None,              # 默认创建第三张表时,数据库中表的名称

3,反向操作

from django db import models

class UserType(models.Model):
	name = models.CharField(max_length=32)
	
class User(models.Model):
	user = models.CharField(max_length=64)
	pwd = models.CharField(max_length=64)
	ut = models.FareignKey(to=‘UserType‘,to_field=‘id‘)
	
v = User.objects.all()
for item in v:
	item.user
	item.pwd
	item.ut.name

User.objects.all().values(‘user‘,‘ut_name‘)


###
v = UserType.objects.all()
for item in v:
	item.name
	item.id
	item.user_set.all()
	
UserType.objects.all().values(‘name‘,‘user_set‘)

4,ORM操作

# 增
        #
        # models.Tb1.objects.create(c1=‘xx‘, c2=‘oo‘)  增加一条数据,可以接受字典类型数据 **kwargs

        # obj = models.Tb1(c1=‘xx‘, c2=‘oo‘)
        # obj.save()

        # 查
        #
        # models.Tb1.objects.get(id=123)         # 获取单条数据,不存在则报错(不建议)
        # models.Tb1.objects.all()               # 获取全部
        # models.Tb1.objects.filter(name=‘seven‘) # 获取指定条件的数据
        # models.Tb1.objects.exclude(name=‘seven‘) # 获取指定条件的数据

        # 删
        #
        # models.Tb1.objects.filter(name=‘seven‘).delete() # 删除指定条件的数据

        # 改
        # models.Tb1.objects.filter(name=‘seven‘).update(gender=‘0‘)  # 将指定条件的数据更新,均支持 **kwargs
        # obj = models.Tb1.objects.get(id=1)
        # obj.c1 = ‘111‘
        # obj.save()                                                 # 修改单条数据基本操作

5,进阶操作

# 获取个数
        #
        # models.Tb1.objects.filter(name=‘seven‘).count()

        # 大于,小于
        #
        # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
        # models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值
        # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lte=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

        # in
        #
        # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
        # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

        # isnull 是否为空 
        # Entry.objects.filter(pub_date__isnull=True)

        # contains (like)
        #
        # models.Tb1.objects.filter(name__contains="ven")
        # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
        # models.Tb1.objects.exclude(name__icontains="ven")

        # range  范围
        #
        # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and

        # 其他类似 xxx开头 xx结尾
        #
        # startswith,istartswith, endswith, iendswith,

        # order by 排序
        #
        # models.Tb1.objects.filter(name=‘seven‘).order_by(‘id‘)    # asc  正向排序
        # models.Tb1.objects.filter(name=‘seven‘).order_by(‘-id‘)   # desc  逆向排序

        # group by  分组 统计
        #
        # from django.db.models import Count, Min, Max, Sum
        # models.Tb1.objects.filter(c1=1).values(‘id‘).annotate(c=Count(‘num‘))
        # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

        # limit 、offset 分页
        #
        # models.Tb1.objects.all()[10:20]

        # regex正则匹配,iregex 不区分大小写
        #
        # Entry.objects.get(title__regex=r‘^(An?|The) +‘)
        # Entry.objects.get(title__iregex=r‘^(an?|the) +‘)
        
        按时间查找
        # date
        #
        # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
        # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

        # year
        #
        # Entry.objects.filter(pub_date__year=2005)
        # Entry.objects.filter(pub_date__year__gte=2005)

        # month
        #
        # Entry.objects.filter(pub_date__month=12)
        # Entry.objects.filter(pub_date__month__gte=6)

        # day
        #
        # Entry.objects.filter(pub_date__day=3)
        # Entry.objects.filter(pub_date__day__gte=3)

        # week_day
        #
        # Entry.objects.filter(pub_date__week_day=2)
        # Entry.objects.filter(pub_date__week_day__gte=2)

        # hour
        #
        # Event.objects.filter(timestamp__hour=23)
        # Event.objects.filter(time__hour=5)
        # Event.objects.filter(timestamp__hour__gte=12)

        # minute
        #
        # Event.objects.filter(timestamp__minute=29)
        # Event.objects.filter(time__minute=46)
        # Event.objects.filter(timestamp__minute__gte=29)

        # second
        #
        # Event.objects.filter(timestamp__second=31)
        # Event.objects.filter(time__second=2)
        # Event.objects.filter(timestamp__second__gte=31)

6,其他操作

##################################################################
# PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
##################################################################

def all(self)
    # 获取所有的数据对象

def filter(self, *args, **kwargs)
    # 条件查询
    # 条件可以是:参数,字典,Q

def exclude(self, *args, **kwargs)
    # 条件查询
    # 条件可以是:参数,字典,Q

def select_related(self, *fields)
     性能相关:表之间进行join连表操作,一次性获取关联的数据。
     model.tb.objects.all().select_related()
     model.tb.objects.all().select_related(‘外键字段‘)
     model.tb.objects.all().select_related(‘外键字段__外键字段‘)

def prefetch_related(self, *lookups)
    性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。
            # 获取所有用户表
            # 获取用户类型表where id in (用户表中的查到的所有用户ID)
            models.UserInfo.objects.prefetch_related(‘外键字段‘)



            from django.db.models import Count, Case, When, IntegerField
            Article.objects.annotate(
                numviews=Count(Case(
                    When(readership__what_time__lt=treshold, then=1),
                    output_field=CharField(),
                ))
            )

            students = Student.objects.all().annotate(num_excused_absences=models.Sum(
                models.Case(
                    models.When(absence__type=‘Excused‘, then=1),
                default=0,
                output_field=models.IntegerField()
            )))

def annotate(self, *args, **kwargs)
    # 用于实现聚合group by查询

    from django.db.models import Count, Avg, Max, Min, Sum

    v = models.UserInfo.objects.values(‘u_id‘).annotate(uid=Count(‘u_id‘))
    # SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id

    v = models.UserInfo.objects.values(‘u_id‘).annotate(uid=Count(‘u_id‘)).filter(uid__gt=1)
    # SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1

    v = models.UserInfo.objects.values(‘u_id‘).annotate(uid=Count(‘u_id‘,distinct=True)).filter(uid__gt=1)
    # SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1

def distinct(self, *field_names)
    # 用于distinct去重
    models.UserInfo.objects.values(‘nid‘).distinct()
    # select distinct nid from userinfo

    注:只有在PostgreSQL中才能使用distinct进行去重

def order_by(self, *field_names)
    # 用于排序
    models.UserInfo.objects.all().order_by(‘-id‘,‘age‘)

def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
    # 构造额外的查询条件或者映射,如:子查询

    Entry.objects.extra(select={‘new_id‘: "select col from sometable where othercol > %s"}, select_params=(1,))
    Entry.objects.extra(where=[‘headline=%s‘], params=[‘Lennon‘])
    Entry.objects.extra(where=["foo=‘a‘ OR bar = ‘a‘", "baz = ‘a‘"])
    Entry.objects.extra(select={‘new_id‘: "select id from tb where id > %s"}, select_params=(1,), order_by=[‘-nid‘])

 def reverse(self):
    # 倒序
    models.UserInfo.objects.all().order_by(‘-nid‘).reverse()
    # 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序


 def defer(self, *fields):
    models.UserInfo.objects.defer(‘username‘,‘id‘)
    或
    models.UserInfo.objects.filter(...).defer(‘username‘,‘id‘)
    #映射中排除某列数据

 def only(self, *fields):
    #仅取某个表中的数据
     models.UserInfo.objects.only(‘username‘,‘id‘)
     或
     models.UserInfo.objects.filter(...).only(‘username‘,‘id‘)

 def using(self, alias):
     指定使用的数据库,参数为别名(setting中的设置)


##################################################
# PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
##################################################

def raw(self, raw_query, params=None, translations=None, using=None):
    # 执行原生SQL
    models.UserInfo.objects.raw(‘select * from userinfo‘)

    # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名
    models.UserInfo.objects.raw(‘select id as nid from 其他表‘)

    # 为原生SQL设置参数
    models.UserInfo.objects.raw(‘select id as nid from userinfo where nid>%s‘, params=[12,])

    # 将获取的到列名转换为指定列名
    name_map = {‘first‘: ‘first_name‘, ‘last‘: ‘last_name‘, ‘bd‘: ‘birth_date‘, ‘pk‘: ‘id‘}
    Person.objects.raw(‘SELECT * FROM some_other_table‘, translations=name_map)

    # 指定数据库
    models.UserInfo.objects.raw(‘select * from userinfo‘, using="default")

    ################### 原生SQL ###################
    from django.db import connection, connections
    cursor = connection.cursor()  # cursor = connections[‘default‘].cursor()
    cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    row = cursor.fetchone() # fetchall()/fetchmany(..)


def values(self, *fields):
    # 获取每行数据为字典格式

def values_list(self, *fields, **kwargs):
    # 获取每行数据为元祖

def dates(self, field_name, kind, order=‘ASC‘):
    # 根据时间进行某一部分进行去重查找并截取指定内容
    # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
    # order只能是:"ASC"  "DESC"
    # 并获取转换后的时间
        - year : 年-01-01
        - month: 年-月-01
        - day  : 年-月-日

    models.DatePlus.objects.dates(‘ctime‘,‘day‘,‘DESC‘)

def datetimes(self, field_name, kind, order=‘ASC‘, tzinfo=None):
    # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
    # kind只能是 "year", "month", "day", "hour", "minute", "second"
    # order只能是:"ASC"  "DESC"
    # tzinfo时区对象
    models.DDD.objects.datetimes(‘ctime‘,‘hour‘,tzinfo=pytz.UTC)
    models.DDD.objects.datetimes(‘ctime‘,‘hour‘,tzinfo=pytz.timezone(‘Asia/Shanghai‘))

    """
    pip3 install pytz
    import pytz
    pytz.all_timezones
    pytz.timezone(‘Asia/Shanghai’)
    """

def none(self):
    # 空QuerySet对象


####################################
# METHODS THAT DO DATABASE QUERIES #
####################################

def aggregate(self, *args, **kwargs):
   # 聚合函数,获取字典类型聚合结果
   from django.db.models import Count, Avg, Max, Min, Sum
   result = models.UserInfo.objects.aggregate(k=Count(‘u_id‘, distinct=True), n=Count(‘nid‘))
   ===> {‘k‘: 3, ‘n‘: 4}

def count(self):
   # 获取个数

def get(self, *args, **kwargs):
   # 获取单个对象

def create(self, **kwargs):
   # 创建对象

def bulk_create(self, objs, batch_size=None):
    # 批量插入
    # batch_size表示一次插入的个数
    objs = [
        models.DDD(name=‘r11‘),
        models.DDD(name=‘r22‘)
    ]
    models.DDD.objects.bulk_create(objs, 10)

def get_or_create(self, defaults=None, **kwargs):
    # 如果存在,则获取,否则,创建
    # defaults 指定创建时,其他字段的值
    obj, created = models.UserInfo.objects.get_or_create(username=‘root1‘, defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 2})

def update_or_create(self, defaults=None, **kwargs):
    # 如果存在,则更新,否则,创建
    # defaults 指定创建时或更新时的其他字段
    obj, created = models.UserInfo.objects.update_or_create(username=‘root1‘, defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 1})

def first(self):
   # 获取第一个

def last(self):
   # 获取最后一个

def in_bulk(self, id_list=None):
   # 根据主键ID进行查找
   id_list = [11,21,31]
   models.DDD.objects.in_bulk(id_list)

def delete(self):
   # 删除

def update(self, **kwargs):
    # 更新

def exists(self):
   # 是否有结果

其他操作
select id,count(id) from tab1 group by id having count(id) > 15;

#Entry 跨表查询 select,where
#select 
Entry.objects.filter().extra(select={‘cid‘: "%s"},select_params=[1])
select * 1 as cid from tab1;

Entry.objects.extra(select={‘new_id‘: "select col from sometable where othercol = %s" },select_params=[1])

select * (select name from tab2 where nid = id) as new_id from tab1;

Entry.objects.extra(select={‘new_id‘: "func(id)"})
select * (select name from tb2 where nid = id) as new_id from tab1;

#where
Entry.objects.extra(where=[‘headline=1‘,‘nid>1‘])
Entry.objects.extra(where=[‘headline=1 or nid=1‘])
Entry.objects.extra(where=[‘func(ctime)=1 or nid=1‘],params=[])

7,高效率关联表

select_related
	users = models.User.objects.all().select_related(‘ut‘)
	for row in users:
		print(row.user,row.pwd,row.ut_id)
		print(row.ut.name)
		print(row.tu.name)  #再发一次SQL请求
		
prefetch_related
	users = models.User.objects.filter(id_gt=30).prefetch_related(‘ut‘,‘tu‘)
	select * from users where id > 30
	select * from user_type where id in [1,2]
	
	for row in users:
		print(row.user,row.pwd,row.ut_id)
		print(row.ut.name)	

8,models自带验证

obj = models.UserInfo(name=‘alex‘,email=‘alex‘)
obj.full_clean()
obj.save()

return HttpResponse(‘index‘)

9,models内置钩子

class UserInfo(models.Model):
	name = models.CharField(max_length=32)
	c = UserInfo.objects.filter(name=self.name).count()
	if c:
		raise ValidationError(message=‘用户名已经存在‘,code=‘li‘)

##############
from django.forms import vidgets

class UserInForm(forms.Form):
	user = fields.CharField(
		required=False,
		widget=widgets.Textarea(attrs={‘class‘:‘c1‘})
		)
		pwd = fields.CharField(
			max_length=12,
			widget=widgets.PasswordInput(attrs={‘class‘:‘c1‘})
			)
			
			#f 验证
			#生成HTML (保留上一次提交的数据)
			
			#新URL方式操作(Form方式)
			#Ajax请求 验证(*) + 生成HTML 验证(*)

10,from,choices

models.py

from django.db import models

# Create your models here.
class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()

    def clean(self):
        from django.core.exceptions import ValidationError
        c = UserInfo.objects.filter(name=self.name).count()
        if c:
            raise ValidationError(message=‘用户名已经存在‘,code=‘li‘)

class UserType(models.Model):
    name = models.CharField(max_length=32)
    
   def __str__(self):
        return self.name

###########
from.py

from django.forms import widgets
from django import forms
from django.forms import fields
from app import models
from django.forms.models import ModelChoiceField,ModelMultipleChoiceField

class UserInfoForm(forms.Form):
    user = fields.CharField(
        required=False,
        widget=widgets.Textarea(attrs={‘class‘:‘c1‘})
    )
    pwd = fields.CharField(
        max_length=12,
        widget=widgets.PasswordInput(attrs={‘class‘:‘c1‘})
    )

    user_type = fields.ChoiceField(
    choices = [],
    widget=widgets.Select
    )

    user_type2 = fields.ChoiceField(widget=widgets.Select(choices=[]))
    
    #django自带
    #ModelMultipleChoiceField多选
     user_type3 = ModelChoiceField(
        empty_label=‘请选择类型‘,
        queryset=models.UserType.objects.all(),
        to_field_name=‘id‘

    )

    def __init__(self,*args,**kwargs):
        super(UserInfoForm,self).__init__(*args,**kwargs)

        self.fields[‘user_type‘].choices = models.UserType.objects.values_list(‘id‘,‘name‘)
        self.fields[‘user_type2‘].widget.choices = models.UserType.objects.values_list(‘id‘,‘name‘)


#########
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>{{ obj.user }}</p>
    <p>{{ obj.pwd }}</p>
    <p>{{ obj.user_type }}</p>
    <p>{{ obj.user_type2 }}</p>
    <p>{{ obj.user_type3 }}</p>
</body>
</html>

11,Form类

创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;

1、Django内置字段如下:

http://www.cnblogs.com/wupeiqi/articles/6144178.html

Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label标签或显示内容 initial=None, 初始值 help_text=‘‘, 帮助信息(在标签旁边显示) error_messages=None, 错误信息 {‘required‘: ‘不能为空‘, ‘invalid‘: ‘格式错误‘} show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直) validators=[], 自定义验证规则 localize=False, 是否支持本地化 disabled=False, 是否可以编辑 label_suffix=None Label内容后缀 CharField(Field) max_length=None, 最大长度 min_length=None, 最小长度 strip=True 是否移除用户输入空白 IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值 FloatField(IntegerField) ... DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 总长度 decimal_places=None, 小数位长度 BaseTemporalField(Field) input_formats=None 时间格式化 DateField(BaseTemporalField) 格式:2015-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 DurationField(Field) 时间间隔:%d %H:%M:%S.%f ... RegexField(CharField) regex, 自定制正则表达式 max_length=None, 最大长度 min_length=None, 最小长度 error_message=None, 忽略,错误信息使用 error_messages={‘invalid‘: ‘...‘} EmailField(CharField) ... FileField(Field) allow_empty_file=False 是否允许空文件 ImageField(FileField) ... 注:需要PIL模块,pip3 install Pillow 以上两个字典使用时,需要注意两点: - form表单中 enctype="multipart/form-data" - view函数中 obj = MyForm(request.POST, request.FILES) URLField(Field) ... BooleanField(Field) ... NullBooleanField(BooleanField) ... ChoiceField(Field) ... choices=(), 选项,如:choices = ((0,‘上海‘),(1,‘北京‘),) required=True, 是否必填 widget=None, 插件,默认select插件 label=None, Label内容 initial=None, 初始值 help_text=‘‘, 帮助提示 ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查询数据库中的数据 empty_label="---------", # 默认空显示内容 to_field_name=None, # HTML中value的值对应的字段 limit_choices_to=None # ModelForm中对queryset二次筛选 ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField TypedChoiceField(ChoiceField) coerce = lambda val: val 对选中的值进行一次转换 empty_value= ‘‘ 空值的默认值 MultipleChoiceField(ChoiceField) ... TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 对选中的每一个值进行一次转换 empty_value= ‘‘ 空值的默认值 ComboField(Field) fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) MultiValueField(Field) PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:[‘%Y--%m--%d‘, ‘%m%d/%Y‘, ‘%m/%d/%y‘] input_time_formats=None 格式列表:[‘%H:%M:%S‘, ‘%H:%M:%S.%f‘, ‘%H:%M‘] FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 允许文件 allow_folders=False, 允许文件夹 required=True, widget=None, label=None, initial=None, help_text=‘‘ GenericIPAddressField protocol=‘both‘, both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用 SlugField(CharField) 数字,字母,下划线,减号(连字符) ... UUIDField(CharField) uuid类型

12,From内置钩子验证

#####
views.py

from django.shortcuts import render
from app.forms import  RegisterForm
# Create your views here.

def index(request):
    if request.method == "GET":
        obj =  RegisterForm()
        #传递默认值
        #obj =  RegisterForm({‘user‘:‘alex‘})
        return render(request,‘index.html‘,{‘obj‘:obj})

    elif request.method == "POST":
        obj =  RegisterForm(request.POST,request.FILES)
        obj.is_valid()

####
froms.py

from django.core.exceptions import ValidationError
class RegisterForm(forms.Form):
    user = fields.CharField()
    email = fields.EmailField


    def clean_user(self):
        c = models.UserInfo.objects.filter(name=self.cleaned_data[‘user‘]).count()
        if not c:
            return self.cleaned_data[‘user‘]
        else:
            raise ValidationError(‘用户名已经存在‘,code=‘xx‘)

    def clean_email(self):
        return self.cleaned_data[‘email‘]

class LoginFrom(forms.Form):
    user = fields.CharField()
    pwd = fields.CharField()
    #自定义表达式
    #pwd = fields.CharField(validators=[])
    
    #验证用户是否存在
    def clean_user(self):
        c = models.UserInfo.objects.filter(name=self.cleaned_data[‘user‘]).count()
        if not c:
            return self.cleaned_data[‘user‘]
        else:
            raise ValidationError(‘用户名已经存在‘, code=‘xx‘)
   
   
    #验证密码是否正确
    def clean(self):
        c = models.UserInfo.objects.filter(name=self.cleaned_data[‘user‘],pwd=self.cleaned_data[‘password‘]).count()
        if c:
            return self.cleaned_data
        else:
            raise ValidationError(‘用户名或密码错误‘)
   
   #其他钩子
    def _post_clean(self):
        pass

from验证

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
#from app import views
from app.views import test
from app.views import account
urlpatterns = [
    #path(‘admin/‘, admin.site.urls),
    url(r‘^index/‘,test.index),
    url(r‘^login.html$‘,account.login),
]

####
index.py

from django.shortcuts import render
from app.forms import UserInfoForm
# Create your views here.

def index(request):
    if request.method == "GET":
        obj = UserInfoForm()
        #传递默认值
        #obj = UserInfoForm({‘user‘:‘alex‘})
        return render(request,‘index.html‘,{‘obj‘:obj})

    elif request.method == "POST":
        obj = UserInfoForm(request.POST,request.FILES)
        obj.is_valid()


####
login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
    <form id="fm">
        {% csrf_token %}
        <p><input type="text" name="username" /></p>
        <p><input type="text" name="password" /></p>
        <a id="submit">提交</a>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        $(function(){
            $(‘$submit‘).click(function(){
                $.ajax({
                    url:‘/login.html‘,
                    type: ‘POST‘,
                    data: $(‘#fm‘).serialize(),
                    success: function(arg){
                        arg = JSON.parse(arg);
                        console.log(arg);
                    },
                    error: function(){

                    }
                })
            })
        })
    </script>
</body>
</html>

####
account.py

from django.forms import fields
from django.forms import widgets
from django import forms
from django.shortcuts import render,HttpResponse
class LoginFrom(forms.Form):
    username = fields.CharField()
    password = fields.CharField(
        max_length=64,
        min_length=12,
    )

###自定义jsnon 默认json只支持python类型
from django.core.exceptions import ValidationError
import json
class JsonCustomEncoder(json.JSONEncoder):
    def default(self,field):
        if isinstance(field,ValidationError):
            return {‘code‘: field.code,‘messages‘:field.message}
        else:
            return json.JSONEncoder.default(self,field)


def login(request):
    if request.method == ‘GET‘:
        return render(request,‘login.html‘)
    elif request.method == "POST":
        ret = {‘status‘:True,‘error‘:None,‘date‘:None}
        obj = LoginFrom(request.POST)
        if obj.is_valid():
            print(obj.cleaned_data)
        else:
            ret[‘error‘] = obj.error.as_data()
        result = json.dumps(ret,cls=JsonCustomEncoder)
        return HttpResponse(result)  

自定义json

第一种
	from django.core import serializrs
	
	v = models.tb.objects.all()
	data = serializers.serialize("json",v)
	
第二种
	import json
	from datetime import date
	from datetime import datetime
	
	class JsonCustomEncoder(json.JSONEncoder):
		def default(self,field):
			if isinstance(field,datetime):
				return field.atrftime(‘%Y-%m-%d %H:%M:%s‘)
			elif isinstance(field,date):
				return field.strftime(‘%Y-%m-%d‘)
			else:
            	return json.JSONEncoder.default(self,field)
     v = models.tb.objects.values(‘id‘,‘name‘,‘ctime‘)
     v = list(v)
     v = json.dumps(v,cls=JsonCustomEncoder)
     
     
     #####################
     v = models.UserType.objects.values(‘id‘,‘name‘)
     v = list(v)
     return HttpResponse(json.dumps(v))

登录验证吗

if request,method == POST:
	if request.session[‘CheckCode‘].upper() == request.POST.get(‘check_code‘).upper():
		pass
	else:
    	print(‘验证码错误‘)
return render(request,‘login.html‘)    	

12,obj.is_valid()错误信息

from app01.forms import RegisterForm
from django.core.excptions import NON_FIELD_ERRORS
#NON_FIELD_ERRORS = __all__

obj = RegisterForm(request.POST)
if obj.is_valid():
	obj.cleand_data
else:
	obj.errros
	{
        "__all__": [],
        ‘user‘:[{‘code‘:‘required‘,‘message‘:‘xxx‘}],
        ‘pwd‘:[{‘code‘:‘required‘,‘message‘:‘xxx‘}],
	}

  

第八章(5)

标签:ctime   apt   err   nts   gen   nes   get   帮助信息   eric   

原文地址:https://www.cnblogs.com/hanwei999/p/9350280.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!