Python学习---Model拾遗[2]180318

Model的字段及字段参数

Model字段:

  数字
        字符串(带正则的字段)
        时间
        文件
       特殊字段:(一对一,一对多,多对多)

Models.py

1
2
3
4
5
6
7
8
9
10
11
class UserProfile(models.Model):
    pwd = models.CharField(max_length=32)
    email = models.EmailField()  # 有Email验证功能,但是在model里未使用【ModelForm有用到】
    timeStack = models.DateTimeField() # 时间模块
    binary = models.BinaryField()  # 二进制模块
     file = models.FileField(upload_to='upload') # 页面生成input框,数据库内存储字符串,ModelForm里存储文件
    # 页面生成input框,且上传图片会获取到文件大小并赋值给w和h
    # 这里是利用Pillow模块实现,如未安装Pillow,使用ImageField会报错
    w = models.IntegerField()  # 获取Img的大小赋值给w
    h = models.IntegerField()  # 获取Img的大小赋值给h
    img = models.ImageField(upload_to='img',width_field='w', height_field='h')# 注意w和h添加引号的

 

Model字段参数

Model参数: 用于指定数据库列的信息(eg.列名别名,是否添加索引等)

                   用于验证(admin, ModelForm)

                   关系(一对一,一对多,多对多)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
null                数据库中字段是否可以为空
db_column           数据库中字段的列名
default             数据库中字段的默认值
primary_key         数据库中字段是否为主键
db_index            数据库中字段是否可以建立索引
unique              数据库中字段是否可以建立唯一索引
unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
unique_for_month    数据库中字段【月】部分是否可以建立唯一索引
unique_for_year     数据库中字段【年】部分是否可以建立唯一索引
 
verbose_name        Admin中显示的字段名称
blank               Admin中是否允许用户输入为空
editable            Admin中是否可以编辑
help_text           Admin中该字段的提示信息
choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
               如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
 
error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
                    字典健:null, blank, invalid, invalid_choice, unique, and   unique_for_date
                    如:{'null': "不能为空.", 'invalid': '格式错误'}
 
validators          自定义错误验证(列表类型),从而定制想要的验证规则

简单的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from django.core.validators import RegexValidator
from django.core.validators import EmailValidator,
from django.core.validators import URLValidator,MinLengthValidator
from django.core.validators import DecimalValidator,
from django.core.validators import MaxLengthValidator,
from django.core.validators import MaxValueValidator,MinValueValidator
    如:
        test = models.CharField(
            max_length=32,
            error_messages={
                'c1': '优先错信息1',
                'c2': '优先错信息2',
                'c3': '优先错信息3',
            },
            validators=[
                RegexValidator(regex='root_\d+', message='错误了', code='c1'),
                RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
                EmailValidator(message='又错误了', code='c3'), ]
        )

这里重点介绍Model中validators和error_message的用法:

models.py

1
2
3
4
5
6
7
8
9
10
11
12
<pre class="brush: sql; auto-links: true; collapse: false; first-line: 1; gutter: html-script: light: ruler: smart-tabs: tab-size: 4; toolbar:">from django.core.validators import RegexValidator
from django.core.validators import EmailValidator, URLValidator, DecimalValidator
from django.core.validators import MaxValueValidator, MinValueValidator
from django.core.validators import MaxLengthValidator, MinLengthValidator
class Regex(models.Model):
    name = models.CharField(max_length=32, error_messages={'required':'Model里设置的错误信息error_message'},)
    title = models.CharField(max_length=32, error_messages={'c1': '自定义关键字报错'},
                             validators=[
                                 RegexValidator(regex='root_\d+', message='错误了', code='c1'),
                                RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
                                 EmailValidator(message='Email错误了,未用到', code='c3'), ]
                             )</pre><br><strong>注意:</strong><br>    1.ModelForm里面定义Form的优先级高于Model<br>    2.Model中title的error_message里面的自定义的代码是c1,页面显示的也是C1里面定义的内容,所以error_message比Validators的级别高。<br>    3.如果想定义中文显示,只能去DjangoAdmin里面修改ModelForm了

admin.py

1
2
3
from django.contrib import admin
from app01 import models
admin.site.register(models.Regex)

页面显示:

image

初始化数据库

1
2
python manage.py makemigrations
python manage.py migrate

多表关系以及参数

外键:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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中是否显示关联数据

一对一:

1
2
3
4
5
6
7
8
9
10
11
to
to_field
related_name
related_query_name
limti_choices_to = {}
verbose_name
select_related
prefetch_related
on_delete
db_constraint
parent_link: 是否创建父亲页面的显示

多对多:

【更多参考】http://www.cnblogs.com/wupeiqi/articles/6216618.html

Model之ORM操作大总结

基本操作+高级操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 增
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() # 删除指定条件的数据
 
# 改
 # 将指定条件的数据更新,均支持 **kwargs
models.Tb1.objects.filter(name='seven').update(gender='0')
 
# 修改单条数据
obj = models.Tb1.objects.get(id=1)
obj.c1 = '111'
obj.save()                                               
# 获取个数
    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
    models.Tbl.objects.filter(pub_date__isnull=True) # 获取条件为空
# contains 模糊匹配
    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
# 其他类似
    models.Tb1.objects.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
# annotate  ==》group by
    from django.db.models import Count, Min, Max, Sum
    # 对Values里面的id进行groupBy,所以values必须放前面
    # 前面的filter表示sql里面的where; 如果filter放在后面则表示Having
    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"
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
 
# 切片: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)

高级操作和其他操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# F操作
    from django.db.models import F
    models.Tb1.objects.update(num=F('num')+1)
 
# Q操作
   #方式一:
    Q(nid__gt=10)
    Q(nid=8) | Q(nid__gt=10)
    Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
  # 方式二:
    con = Q()
    q1 = Q()
    q1.connector = 'OR'
    q1.children.append(('id', 1))
    q1.children.append(('id', 10))
    q1.children.append(('id', 9))
    q2 = Q()
    q2.connector = 'OR'
    q2.children.append(('c1', 1))
    q2.children.append(('c1', 10))
    q2.children.append(('c1', 9))
    con.add(q1, 'AND')
    con.add(q2, 'AND')
    models.Tb1.objects.filter(con)
 
# extra: 自己写复杂是sql
   extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
   # select_params和select对应
   # where 和 params对应
   Tbl.objects.extra(select={'new_id': "1"},)
   # select XXX,  1  from Entry;  ==> 第二列的数据为1
   Tbl.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
   # select XXX, (select col from sometable where othercol > 1) as new_id from Entry;
   Tbl.objects.extra(where=['headline=%s'], params=['Lennon'])
   # select XXX from Entry where headline="Lennon";
   Tbl.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"]) # 双引号内是or条件,逗号是and条件
   # select XXX from Entry where (foo='a' or bar='a') and baz='a';  ==>类似于Q的写法
   Tbl.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
   # select XXX, (select col from sometable where othercol > 1) as new_id from Entry order by nid desc;
 
# 执行原生SQL:适合sql复杂,Django解决不了用
 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()
 row = cursor.fetchmany()
     
# 多个数据库的使用:
settings.py 这里定义了2个数据库,2个相同的数据库,可交叉使用,可一个读一个写
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
    'default1': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db1.sqlite3'),
    }
}
models.Regex.objects.filter(id__lt = 4).using('default1')  # 使用default1
 
上面调用原生态sql的时候也可以使用
from django.db import connection, connections
 cursor = connections['default1'].cursor()  # 使用default1数据库
 cursor.execute("""SELECT * from auth_user where id = %s""", [1])
 row = cursor.fetchone()
 row = cursor.fetchmany()

Model之QuerySet()方法剖析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
##################################################################
# 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连表操作,一次性获取关联的数据。
select_related()仅仅适用于外键字段进行关联,如果有多级的字段关联,多写2个下划线表示
     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.all().prefetch_related('外键字段')
# 第一次从数据库内获取符合条件的数据时,会获取到该数据中外键字段【假设有10个数据,其中2个符合要求】,从而在第三张表中查询符合条件的数据【2条数据】放入内存中,下次obj.user_type_cap获取内容的时候就会从内存中获取了,减少了数据库的操作。
            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则是倒序,如果多个排序则一一倒序
这个reserve会检查是否有order_by,有则倒叙,无责不操作。  all().reserver() 无效果
 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, 此时将数据库内查询的列对应到model里面的字段
    models.UserInfo.objects.raw('select * from userinfo')
 
    # 如果SQL是其他表时,必须查询对象主键,且将名字设置为当前UserInfo对象的主键列名
user是userinfo的字段,caption是userType的字段
    models.UserInfo.objects.raw('select id,caption as user 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 如果获取的是year关键字,则Django返回我们年
 
        - month: 年-月-01   如果获取的是month关键字,则Django返回我们年月
        - day  : 年-月-日 ,如果获取的是day关键字,则Django返回我们年月日
 
    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'))
 
    """
Datetimes模块需要Python安装如下的模块:
    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} # 获取nid的数量,且可以有去重操作
 
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) # 这里一条sql创建10次,objs内有2条,共20条
 
def get_or_create(self, defaults=None, **kwargs):
    # 如果存在,则获取,否则,创建
    # 根据username进行查询【支持多个条件查询】,没有则根据查找的值 + defaults创建其他字段    obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2})
obj, created = models.UserInfo.objects.get_or_create(username='root1', pwd=’123456’,defaults={'email': '1111111','u_id': 2, 't_id': 2})
# 根据username&&pwd来查询对象,没有则根据usename,pwd 和default创建这个值
# obj永远表示获取的对象,有则直接获取,无责创建后获取
# created则表示是否创建了对象,只有truefalse共2个值
# create仅仅能创建一个值
 
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]  # 等价于 model.objects.filter(id__in=[11,21,31])
   models.DDD.objects.in_bulk(id_list)
 
def delete(self):
   # 删除
 
def update(self, **kwargs):
    # 更新
 
def exists(self):
   # 是否有结果

获取对象的指定列: values(),values_lis()获取的都是列表非对象

获取全部对象的全部列:all(),filter()获取的都是全部对象的全部列

defer()内写那一列就不获取该列的数据。但是任然可以使用defer()内的字段,因为你用的时候Django会自动发送一个sql请求去查找了。所以一个原则是:不需要谁就写谁,且拿到的是对象请求

only():表示只获取某几个字段,拿过来以后任然是对象类型

1
2
3
4
原生态的sql执行:
extra()方法
raw()方法
Connections()   

Model之model错误信息操作

Model对象调用full_clean()方法后,full_clean()会自动去掉用Model函数中覆写的clean()方法执行我们创建内容的正确性。

注意:

1.对比Form,这个里面没有clean_字段名(),这个方法,因为Form是用户发送过来的请求

      Model里面是我们自己创建的内容

2.full_clean()方法因为无法自动捕获异常,所以需要我们调用的时候,手动去捕获异常

models.py

1
2
3
4
5
6
7
8
9
10
from django.db import models
class U(models.Model):
    id = models.AutoField(primary_key=True)  # AutoField必须是主键,才能自定义该列
    name = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    
    # 自定义方法进行内容验证,能抛出异常【obj.full_clean()方法内调用clean()】
    def clean(self):
        if(self.name == 'root1002'):
            print("这里是Model里面自定义的内容验证...")

views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
from app01 import models
from django.shortcuts import render, HttpResponse
from django.forms import fields
from django.forms import63+ forms
 
def test(request):
    # 这里的name=root1002会在Models.py中U的类中进行校验
    obj = models.U(name='root1002', email='hhh@live.com')
    try:
        obj.full_clean()
    except Exception as e:
        print(e)
    obj.save()

Model内部的full_clean()

image

posted @   小a玖拾柒  阅读(220)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 上周热点回顾(1.20-1.26)
· 【译】.NET 升级助手现在支持升级到集中式包管理
点击右上角即可分享
微信分享提示