模型系統(ORM)
一、ORM介紹
1.1、ORM概念
對象關系映射(object elational Mapping,簡稱ORM)模式是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術。
簡單的說,ORM是通過使用描述對象和書庫之間映射的元數據,將程序中的對象自動持久化到關系數據庫中。
ORM在業務邏輯層和數據庫層之間充當了橋梁的作用。
1.2、ORM由來
讓我們重O/R開始,字母O起源於‘對象’(object),而R則來自於‘關系’(Relational)。
幾乎所有的軟件開發過程中都會涉及到對象和關系數據庫。在用戶層面和業務邏輯層面,我們是面向對象的,當對象的信息發生變化的時候,我們就需要把對象的信息保存在關系數據庫中。
按照之前的方式來進行開發就會出現程序員會在自己的業務邏輯代碼中夾雜很多sql語句用來增加、讀取、修改、刪除相關數據,而這些代碼通常都是極其相似或者重復的。
1.3、ORM的優勢
ORM解決的主要問題是對象和關系的映射。它通常將一個類和一張表一一對應,類的每個實例對應表中的一條記錄,類的每個屬性對應表中的每個字段。
ORM提供了對數據庫的映射,不用直接編寫sql代碼,只需操作對象就能對數據庫操作數據。
讓軟件開發人員專注於業務邏輯的處理,提高了開發效率。
1.4、ORM的劣勢
ORM的缺點是會在一定程度上犧牲程序的執行效率。
ORM的操作是有限的,也就是ORM定義好的操作是可以完成的,一些復雜的查詢操作是完成不了的。
二、Django中的ORM
1、Model詳解
1、model的定義
在Django中model是你數據的單一、明確的信息來源。它包含了你存儲的數據的重要字段和行為。通常,一個模型(model)映射到一個數據庫表。
定義簡介:
- 每個模型都是一個python類,它是django.db.models.Model的子類
- 模型的每個屬性都代表一個數據庫字段
- 綜上所述,Django為您提供了一個自動生成的數據庫訪問API,詳細見官方文檔。
model與數據庫結構對應關系圖如下:
2、快速入門
下面舉類詳細分析model如何創建類,及各個語法的意義,如定義一個Person模型,包含兩個屬性first_name和last_name.
from django.db import models class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30)
def Meta(self):
db_table = 'person'
每個類都必須繼承models.Model
first_name 和last_name 是模型的字段,每個字段被指定為一個類屬性,每個屬性映射到一個數據庫表的列。
上面的Person模型將會如下面sql語句在數據庫中創建一個表:
create table myapp_person( 'id':serial not null primary key, 'first_name' varchar(30) not null, 'last_name' varchar(30) not null, );
說明:
- 表myapp_person的名稱是自動生成的,默認數據庫中生成的表名為:appName_類名,如果想自定義表名,需在model中定義方法Meta 指定db_table參數,強烈建議使用小寫表名,特別是使用mysql作為數據庫(默認大小不區分)。
- id 字段是自動添加的且為主鍵,如果想指定自定義主鍵,只需在其中一個字段中指定primary_key= True 即可。如果Django發現你已經明確的設置了Field.primary_key,它將不會添加自動Id列。
- Django支持Mysql5.5及更高版本。
3、Django模型model中的常用字段
AutoField
自增的整形字段,必填參數primary_key=True,則成為數據庫的主鍵,無該字段時,django自動創建。
一個model不能有兩個AutoField字段。
IntegerField
一個整數類型,數值的范圍是-214483648-314783647
CharField
字符類型,對應mysql中的varchar類型,必須提供max_length參數,表示字符的長度。
DateField
日期類型,日期格式為YYYY-MM-DD,相當於python中的datetime.date的實例。
參數:
auto_now: 每次修改時修改為當前日期時間。
auto_now_add: 新創建對象時自動添加當前日期時間。
上面兩個參數和default參數是互斥的,不能同時設置。
DatetimeField
日期時間字段,格式為YYYY-MM-DD HH:MM:[:ss[.uuuuuu][TZ]],相當於python中的atetime.datetime的實例。
字段類型,詳情可點擊查詢官網。

AutoField(Field) - int自增列,必須填入參數 primary_key=True BigAutoField(AutoField) - bigint自增列,必須填入參數 primary_key=True 注:當model中如果沒有自增列,則自動會創建一個列名為id的列 from django.db import models class UserInfo(models.Model): # 自動創建一個列名為id的且為自增的整數列 username = models.CharField(max_length=32) class Group(models.Model): # 自定義自增列 nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) SmallIntegerField(IntegerField): - 小整數 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正小整數 0 ~ 32767 IntegerField(Field) - 整數列(有符號的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正整數 0 ~ 2147483647 BigIntegerField(IntegerField): - 長整型(有符號的) -9223372036854775808 ~ 9223372036854775807 BooleanField(Field) - 布爾值類型 NullBooleanField(Field): - 可以為空的布爾值 CharField(Field) - 字符類型 - 必須提供max_length參數, max_length表示字符長度 TextField(Field) - 文本類型 EmailField(CharField): - 字符串類型,Django Admin以及ModelForm中提供驗證機制 IPAddressField(Field) - 字符串類型,Django Admin以及ModelForm中提供驗證 IPV4 機制 GenericIPAddressField(Field) - 字符串類型,Django Admin以及ModelForm中提供驗證 Ipv4和Ipv6 - 參數: protocol,用於指定Ipv4或Ipv6, 'both',"ipv4","ipv6" unpack_ipv4, 如果指定為True,則輸入::ffff:192.0.2.1時候,可解析為192.0.2.1,開啟此功能,需要protocol="both" URLField(CharField) - 字符串類型,Django Admin以及ModelForm中提供驗證 URL SlugField(CharField) - 字符串類型,Django Admin以及ModelForm中提供驗證支持 字母、數字、下划線、連接符(減號) CommaSeparatedIntegerField(CharField) - 字符串類型,格式必須為逗號分割的數字 UUIDField(Field) - 字符串類型,Django Admin以及ModelForm中提供對UUID格式的驗證 FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供讀取文件夾下文件的功能 - 參數: path, 文件夾路徑 match=None, 正則匹配 recursive=False, 遞歸下面的文件夾 allow_files=True, 允許文件 allow_folders=False, 允許文件夾 FileField(Field) - 字符串,路徑保存在數據庫,文件上傳到指定目錄 - 參數: upload_to = "" 上傳文件的保存路徑 storage = None 存儲組件,默認django.core.files.storage.FileSystemStorage ImageField(FileField) - 字符串,路徑保存在數據庫,文件上傳到指定目錄 - 參數: upload_to = "" 上傳文件的保存路徑 storage = None 存儲組件,默認django.core.files.storage.FileSystemStorage width_field=None, 上傳圖片的高度保存的數據庫字段名(字符串) height_field=None 上傳圖片的寬度保存的數據庫字段名(字符串) DateTimeField(DateField) - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field) - 時間格式 HH:MM[:ss[.uuuuuu]] DurationField(Field) - 長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值為datetime.timedelta類型 FloatField(Field) - 浮點型 DecimalField(Field) - 10進制小數 - 參數: max_digits,小數總長度 decimal_places,小數位長度 BinaryField(Field) - 二進制類型 字段類型
4、自定義字段
自定義一個二進制字段,以及Django字段與數據庫字段類型的對應關系。

class UnsignedIntegerField(models.IntegerField): def db_type(self, connection): return 'integer UNSIGNED' # PS: 返回值為字段在數據庫中的屬性。 # Django字段與數據庫字段類型對應關系如下: 'AutoField': 'integer AUTO_INCREMENT', 'BigAutoField': 'bigint AUTO_INCREMENT', 'BinaryField': 'longblob', 'BooleanField': 'bool', 'CharField': 'varchar(%(max_length)s)', 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', 'DateField': 'date', 'DateTimeField': 'datetime', 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', 'DurationField': 'bigint', 'FileField': 'varchar(%(max_length)s)', 'FilePathField': 'varchar(%(max_length)s)', 'FloatField': 'double precision', 'IntegerField': 'integer', 'BigIntegerField': 'bigint', 'IPAddressField': 'char(15)', 'GenericIPAddressField': 'char(39)', 'NullBooleanField': 'bool', 'OneToOneField': 'integer', 'PositiveIntegerField': 'integer UNSIGNED', 'PositiveSmallIntegerField': 'smallint UNSIGNED', 'SlugField': 'varchar(%(max_length)s)', 'SmallIntegerField': 'smallint', 'TextField': 'longtext', 'TimeField': 'time', 'UUIDField': 'char(32)',
自定義一個char類型字段:

class MyCharField(models.Field): """ 自定義的char類型的字段類 """ def __init__(self, max_length, *args, **kwargs): self.max_length = max_length super(MyCharField, self).__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection): """ 限定生成數據庫表的字段類型為char,長度為max_length指定的值 """ return 'char(%s)' % self.max_length
使用自定義char類型字段

class Class(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=25) # 使用自定義的char類型的字段 cname = MyCharField(max_length=25)
5、字段參數
字段參數,詳情可點擊查看官網。
1 null 數據庫中字段是否可以為空 2 db_column 數據庫中字段的列名 3 default 數據庫中字段的默認值 4 primary_key 數據庫中字段是否為主鍵 5 db_index 數據庫中字段是否可以建立索引 6 unique 數據庫中字段是否可以建立唯一索引 7 unique_for_date 數據庫中字段【日期】部分是否可以建立唯一索引 8 unique_for_month 數據庫中字段【月】部分是否可以建立唯一索引 9 unique_for_year 數據庫中字段【年】部分是否可以建立唯一索引 10 11 verbose_name Admin中顯示的字段名稱 12 blank Admin中是否允許用戶輸入為空 13 editable Admin中是否可以編輯 14 help_text Admin中該字段的提示信息 15 choices Admin中顯示選擇框的內容,用不變動的數據放在內存中從而避免跨表操作 16 如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1) 17 18 error_messages 自定義錯誤信息(字典類型),從而定制想要顯示的錯誤信息; 19 字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date 20 如:{'null': "不能為空.", 'invalid': '格式錯誤'} 21 22 validators 自定義錯誤驗證(列表類型),從而定制想要的驗證規則 23 from django.core.validators import RegexValidator 24 from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\ 25 MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator 26 如: 27 test = models.CharField( 28 max_length=32, 29 error_messages={ 30 'c1': '優先錯信息1', 31 'c2': '優先錯信息2', 32 'c3': '優先錯信息3', 33 }, 34 validators=[ 35 RegexValidator(regex='root_\d+', message='錯誤了', code='c1'), 36 RegexValidator(regex='root_112233\d+', message='又錯誤了', code='c2'), 37 EmailValidator(message='又錯誤了', code='c3'), ] 38 )
6、Model Meta 參數
在指定自定義表名,配置多個數據庫時,要配置其屬性,詳情點擊查看官網。
1 class UserInfo(models.Model): 2 nid = models.AutoField(primary_key=True) 3 username = models.CharField(max_length=32) 4 5 class Meta: 6 # 數據庫中生成的表名稱 默認 app名稱 + 下划線 + 類名 7 db_table = "table_name" 8 9 # admin中顯示的表名稱 10 verbose_name = '個人信息' 11 12 # verbose_name加s 13 verbose_name_plural = '所有用戶信息' 14 15 # 聯合索引 16 index_together = [ 17 ("pub_date", "deadline"), # 應為兩個存在的字段 18 ] 19 20 # 聯合唯一索引 21 unique_together = (("driver", "restaurant"),) # 應為兩個存在的字段
7、多表關系和參數
1 ForeignKey(ForeignObject) # ForeignObject(RelatedField) 2 to, # 要進行關聯的表名 3 to_field=None, # 要關聯的表中的字段名稱 4 on_delete=None, # 當刪除關聯表中的數據時,當前表與其關聯的行的行為 5 - models.CASCADE,刪除關聯數據,與之關聯也刪除 6 - models.DO_NOTHING,刪除關聯數據,引發錯誤IntegrityError 7 - models.PROTECT,刪除關聯數據,引發錯誤ProtectedError 8 - models.SET_NULL,刪除關聯數據,與之關聯的值設置為null(前提FK字段需要設置為可空) 9 - models.SET_DEFAULT,刪除關聯數據,與之關聯的值設置為默認值(前提FK字段需要設置默認值) 10 - models.SET,刪除關聯數據, 11 a. 與之關聯的值設置為指定值,設置:models.SET(值) 12 b. 與之關聯的值設置為可執行對象的返回值,設置:models.SET(可執行對象) 13 14 def func(): 15 return 10 16 17 class MyModel(models.Model): 18 user = models.ForeignKey( 19 to="User", 20 to_field="id" 21 on_delete=models.SET(func),) 22 related_name=None, # 反向操作時,使用的字段名,用於代替 【表名_set】 如: obj.表名_set.all() 23 related_query_name=None, # 反向操作時,使用的連接前綴,用於替換【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名') 24 limit_choices_to=None, # 在Admin或ModelForm中顯示關聯數據時,提供的條件: 25 # 如: 26 - limit_choices_to={'nid__gt': 5} 27 - limit_choices_to=lambda : {'nid__gt': 5} 28 29 from django.db.models import Q 30 - limit_choices_to=Q(nid__gt=10) 31 - limit_choices_to=Q(nid=8) | Q(nid__gt=10) 32 - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root') 33 db_constraint=True # 是否在數據庫中創建外鍵約束 34 parent_link=False # 在Admin中是否顯示關聯數據 35 36 37 OneToOneField(ForeignKey) 38 to, # 要進行關聯的表名 39 to_field=None # 要關聯的表中的字段名稱 40 on_delete=None, # 當刪除關聯表中的數據時,當前表與其關聯的行的行為 41 42 ###### 對於一對一 ###### 43 # 1. 一對一其實就是 一對多 + 唯一索引 44 # 2.當兩個類之間有繼承關系時,默認會創建一個一對一字段 45 # 如下會在A表中額外增加一個c_ptr_id列且唯一: 46 class C(models.Model): 47 nid = models.AutoField(primary_key=True) 48 part = models.CharField(max_length=12) 49 50 class A(C): 51 id = models.AutoField(primary_key=True) 52 code = models.CharField(max_length=1) 53 54 ManyToManyField(RelatedField) 55 to, # 要進行關聯的表名 56 related_name=None, # 反向操作時,使用的字段名,用於代替 【表名_set】 如: obj.表名_set.all() 57 related_query_name=None, # 反向操作時,使用的連接前綴,用於替換【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名') 58 limit_choices_to=None, # 在Admin或ModelForm中顯示關聯數據時,提供的條件: 59 # 如: 60 - limit_choices_to={'nid__gt': 5} 61 - limit_choices_to=lambda : {'nid__gt': 5} 62 63 from django.db.models import Q 64 - limit_choices_to=Q(nid__gt=10) 65 - limit_choices_to=Q(nid=8) | Q(nid__gt=10) 66 - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root') 67 symmetrical=None, # 僅用於多對多自關聯時,symmetrical用於指定內部是否創建反向操作的字段 68 # 做如下操作時,不同的symmetrical會有不同的可選字段 69 models.BB.objects.filter(...) 70 71 # 可選字段有:code, id, m1 72 class BB(models.Model): 73 74 code = models.CharField(max_length=12) 75 m1 = models.ManyToManyField('self',symmetrical=True) 76 77 # 可選字段有: bb, code, id, m1 78 class BB(models.Model): 79 80 code = models.CharField(max_length=12) 81 m1 = models.ManyToManyField('self',symmetrical=False) 82 83 through=None, # 自定義第三張表時,使用字段用於指定關系表 84 through_fields=None, # 自定義第三張表時,使用字段用於指定關系表中那些字段做多對多關系表 85 from django.db import models 86 87 class Person(models.Model): 88 name = models.CharField(max_length=50) 89 90 class Group(models.Model): 91 name = models.CharField(max_length=128) 92 members = models.ManyToManyField( 93 Person, 94 through='Membership', 95 through_fields=('group', 'person'), 96 ) 97 98 class Membership(models.Model): 99 group = models.ForeignKey(Group, on_delete=models.CASCADE) 100 person = models.ForeignKey(Person, on_delete=models.CASCADE) 101 inviter = models.ForeignKey( 102 Person, 103 on_delete=models.CASCADE, 104 related_name="membership_invites", 105 ) 106 invite_reason = models.CharField(max_length=64) 107 db_constraint=True, # 是否在數據庫中創建外鍵約束 108 db_table=None, # 默認創建第三張表時,數據庫中表的名稱
8、ORM常用操作
1 # 增 2 models.Tb1.objects.create(c1='xx', c2='oo') # 增加一條數據,可以接受字典類型數據 **kwargs 3 obj = models.Tb1(c1='xx', c2='oo') 4 obj.save() 5 6 7 # 查 8 models.Tb1.objects.get(id=123) # 獲取單條數據,不存在則報錯(不建議) 9 models.Tb1.objects.all() # 獲取全部 10 models.Tb1.objects.filter(name='seven') # 獲取指定條件的數據 11 models.Tb1.objects.exclude(name='seven') # 去除指定條件的數據 12 13 14 # 刪 15 # models.Tb1.objects.filter(name='seven').delete() # 刪除指定條件的數據 16 17 18 # 改 19 models.Tb1.objects.filter(name='seven').update(gender='0') # 將指定條件的數據更新,均支持 **kwargs 20 obj = models.Tb1.objects.get(id=1) 21 obj.c1 = '111' 22 obj.save() # 修改單條數據
9、ORM進階操作
1 # 獲取個數 2 # 3 # models.Tb1.objects.filter(name='seven').count() 4 5 # 大於,小於 6 # 7 # models.Tb1.objects.filter(id__gt=1) # 獲取id大於1的值 8 # models.Tb1.objects.filter(id__gte=1) # 獲取id大於等於1的值 9 # models.Tb1.objects.filter(id__lt=10) # 獲取id小於10的值 10 # models.Tb1.objects.filter(id__lte=10) # 獲取id小於10的值 11 # models.Tb1.objects.filter(id__lt=10, id__gt=1) # 獲取id大於1 且 小於10的值 12 13 # 成員判斷in 14 # 15 # models.Tb1.objects.filter(id__in=[11, 22, 33]) # 獲取id等於11、22、33的數據 16 # models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in 17 18 # 是否為空 isnull 19 # Entry.objects.filter(pub_date__isnull=True) 20 21 # 包括contains 22 # 23 # models.Tb1.objects.filter(name__contains="ven") 24 # models.Tb1.objects.filter(name__icontains="ven") # icontains大小寫不敏感 25 # models.Tb1.objects.exclude(name__icontains="ven") 26 27 # 范圍range 28 # 29 # models.Tb1.objects.filter(id__range=[1, 2]) # 范圍bettwen and 30 31 # 其他類似 32 # 33 # startswith,istartswith, endswith, iendswith, 34 35 # 排序order by 36 # 37 # models.Tb1.objects.filter(name='seven').order_by('id') # asc 38 # models.Tb1.objects.filter(name='seven').order_by('-id') # desc 39 40 # 分組group by 41 # 42 # from django.db.models import Count, Min, Max, Sum 43 # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num')) 44 # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id" 45 46 # limit 、offset 47 # 48 # models.Tb1.objects.all()[10:20] 49 50 # regex正則匹配,iregex 不區分大小寫 51 # 52 # Entry.objects.get(title__regex=r'^(An?|The) +') 53 # Entry.objects.get(title__iregex=r'^(an?|the) +') 54 55 # date 56 # 57 # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1)) 58 # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1)) 59 60 # year 61 # 62 # Entry.objects.filter(pub_date__year=2005) 63 # Entry.objects.filter(pub_date__year__gte=2005) 64 65 # month 66 # 67 # Entry.objects.filter(pub_date__month=12) 68 # Entry.objects.filter(pub_date__month__gte=6) 69 70 # day 71 # 72 # Entry.objects.filter(pub_date__day=3) 73 # Entry.objects.filter(pub_date__day__gte=3) 74 75 # week_day 76 # 77 # Entry.objects.filter(pub_date__week_day=2) 78 # Entry.objects.filter(pub_date__week_day__gte=2) 79 80 # hour 81 # 82 # Event.objects.filter(timestamp__hour=23) 83 # Event.objects.filter(time__hour=5) 84 # Event.objects.filter(timestamp__hour__gte=12) 85 86 # minute 87 # 88 # Event.objects.filter(timestamp__minute=29) 89 # Event.objects.filter(time__minute=46) 90 # Event.objects.filter(timestamp__minute__gte=29) 91 92 # second 93 # 94 # Event.objects.filter(timestamp__second=31) 95 # Event.objects.filter(time__second=2) 96 # Event.objects.filter(timestamp__second__gte=31)
10、詳細ORM進階操作見
https://www.cnblogs.com/sunxiuwen/p/9644812.html
2、Django項目配置單個app使用Mysql數據庫
1、手動在mysql服務器中創建數據庫:create database db_name charset utf8;
2、創建對應用戶及賦予權限:grant all privileges on db_name.* to 'username'@'ip' identified by 'password';
3、在Django項目的settings.py 文件中,配置數據庫模塊DATABASES的連接信息:
DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "你的數據庫名稱", # 需要自己手動創建數據庫 "USER": "數據庫用戶名", "PASSWORD": "數據庫密碼", "HOST": "數據庫IP", "POST": 3306 } }
4、完成上面步驟后在Django項目全局目錄下,即與manage.py文件同級目錄下的__init__.py文件中導入如下代碼,配置Django項目使用pymsql模塊連接Mysql數據庫:
import pymysql pymyslq.install_as_MySQLdb()
注:如果數據庫遷移的時候出現一個警告,訪問的數據庫沒有在DATABASES中定義,需要在
配置中多家一個OPTIONS參數:
'OPTIONS': { 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
5、數據庫創建好了,在Django中的配置也ok了,后面就在每個app下的models.py文件中創建類了。
from django.db import models # 書 class Book(models.Model): # 必須都繼承models.Model類 title = models.CharField(max_length=32) publish_date = models.DateField(auto_now_add=True) price = models.DecimalField(max_digits=5, decimal_places=2) memo = models.TextField(null=True) # 創建外鍵,關聯publish publisher = models.ForeignKey(to="Publisher") # 創建多對多關聯author author = models.ManyToManyField(to="Author")
6、創建好類后,就需要執行下面的兩個命令,將創建的類(表)同步到數據庫中。
打開cmd,切換到Django項目目錄下:
python manage.py makemigrations app_name
python manage.py migrate app_name
7、完成后,就可以在app目錄下的views.py中通過orm操作數據庫。
from app_name import models def show_class(request): class_list = models.Class.objects.all().order_by('id')
return render(request, 'showclass.html', {'class_list': class_list})
3、Django中配置不同app使用不同的數據庫
詳見連接:https://www.cnblogs.com/zhangxinqi/p/9094953.html
4、content-type組件
https://www.cnblogs.com/GGGG-XXXX/articles/9697458.html
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
# Create your models here.
class Food(models.Model):
"""
id title
1 桃李面包
2 山東大饅頭
"""
title = models.CharField(max_length=32)
# 適用於反向查詢不生成字段
coupons = GenericRelation(to="Coupon")
class Fruit(models.Model):
"""
id title
1 泰國金枕
2 貴妃芒
"""
title = models.CharField(max_length=32)
class Coupon(models.Model):
"""
id title food_id fruit_id
1 山東大饅頭買一送一 2 null
2 買芒果送貴妃 null 2
id title MyTable_id object_id
1 山東大饅頭買一送一 1 2
2 買芒果送貴妃 2 2
"""
title = models.CharField(max_length=32)
# 第一版 多張外鍵關系
# food_obj = models.ForeignKey(to="Food", null=True, blank=True)
# fruit_obj = models.ForeignKey(to="Fruit", null=True, blank=True)
# 第二版 我們自己解決
# MyTable = models.ForeignKey(to="MyTable")
# object = models.IntegerField()
# 第三版 django ContentType
# 第一步 跟ContentType表創建外鍵關系
content_type = models.ForeignKey(to=ContentType)
# 第二步 聲明object_id
object_id = models.IntegerField()
# 第三步 讓content_type, object_id關聯
content_obj = GenericForeignKey("content_type", "object_id")
# Django 給我們提供了這樣一張表
# class MyTable(models.Model):
# """
# id appname tablename
# 1 app02 Food
# 2 app02 Fruit
# """
# # 放app的名字
# app_name = models.CharField(max_length=32)
# # 表名字
# table_name = models.CharField(max_length=32)