1. 程式人生 > >Django之model操作(續)

Django之model操作(續)

class connect public _id hang 多少 datetime sub pan

Django中的源碼續

##################################################
# 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 : 年-月-日 下面這句話就會截取到日,即年月日,如果填寫的是year,則只會取到年 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} result = models.UserInfo.objects.aggregate(n=count(nid))相當於下面sql語句: select count(nid) as n from UserInfo 如果添加distinct=True則先去重在聚合 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) ] 參數10表示一次插入多少個,即將數據進行分批插入 models.DDD.objects.bulk_create(objs, 10) def get_or_create(self, defaults=None, **kwargs): # 如果存在,則獲取,否則,創建 # defaults 指定創建時,其他字段的值,defaults後面的內容表示前面的username不存在的時候,用於創建 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): # 是否有結果

model裏的驗證功能(較弱)

當在models裏寫如下代碼:

class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()

這樣在views函數裏用下面方式添加用戶時:

models.UserInfo.objects.create(name="root",email="123")

或者:

obj = models.UserInfo(name="zhaofan",email = "123")

obj.save()

這種情況下email的格式並不對,但是這樣添加時是可以添加成功,並不會報錯

但是通過obj = models.UserInfo(name="zhaofan",email = "123")方式添加用戶時,obj這裏有一個方法full_clean(),當添加這個方法的時候就會添加驗證功能,完整代碼如下:

obj = models.UserInfo(name="zhaofan",email = "123")

obj.full_clean()

obj.save()

這樣就會提示如下錯誤:

技術分享

查看full_clean源碼

技術分享

可以看出clean_fields是對各個字段進行驗證

下面還有一個clean方法,查看源碼

技術分享

可以看出這裏是Django預留的一個鉤子

對於這個clean鉤子的一個使用例子:

from django.core.exceptions import  ValidationError
class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()
 
    def clean(self):
        c = UserInfo.objects.filter(name=self.name).count()
        if c:
            raise ValidationError(message="用戶名已經存在",code="cc1")

這裏通過clean定制了一個name值唯一的操作

這裏需要知道full_clean驗證的順序:

1、 驗證每個字段的正則

2、 驗證clean鉤子函數

Django之model操作(續)