標籤:htm 圖片 衝突 現象 filter gis through ... 注意
Model: 強大的資料庫操作,弱小的資料驗證
Form: 強大的資料驗證
ModelForm: 強大的資料驗證 + 弱小的資料庫操作
Model
拾遺 Model基本操作
1. 建立資料庫表
2. 修改表層級和行層級的資料
2.1 資料表操作
1.代碼優先【Code First】: 建立類 --> 自動產生表 【Django】
2.資料庫優先【DataBase First】: 建立表 --> 自動產生類 【Hibernate&Mybatit】
單 表:
一對一:
一對多:只能ForeignKey, 有約束關係
註:一對多在多的一方建立ForeignKey[從sql角度看清楚]
多對多:1. Django幫我們建立第三張表
models.ManyToManyField -->類中不添加任何欄位,只是幫我們建立第三張表
2. 我們自己建立第三張表【推薦】
1. 建立一個類,定義2個外鍵,此時表關係一目瞭然
3. 我們自己建立第三張表,且讓Django來引用
註:多對多隻涉及正反尋找問題,寫在任意一個類即可
利用ManyToManyField建立第三張表的時候,DJangoAdmin裡面新增內容是會有該欄位內容
自訂的第三張表需要添加Favor類到admin裡才能顯示
2.2 資料行操作
使用Django幫我們建立第三張表效果:
settings.py
INSTALLED_APPS = [ ... ‘app01‘, # 註冊app]STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 現添加的配置,這裡是元組,注意逗號TEMPLATES = [ ... ‘DIRS‘: [os.path.join(BASE_DIR, ‘templates‘)],]
urls.py
from django.contrib import adminfrom django.urls import pathfrom django.conf.urls import url, includefrom app01 import viewsurlpatterns = [ ]
views.py
from django.shortcuts import render, redirect, HttpResponsefrom app01 import models
models.py
from django.db import modelsclass User(models.Model): id = models.AutoField(primary_key=True) # AutoField必須是主鍵,才能自訂該列 name = models.CharField(max_length=32) userType = models.ForeignKey("UserType", on_delete=True)# 1對多[無法用自訂,有約束關係] # 多對多[1. 自己建立第三張表 2. manytomany ] # 在DjangoAdmin裡面如果自己建立第三張表,則DjangoAdmin裡面不會有下拉框 # ManytoMany建立約束後,DjangoAdmin裡面會有下拉框[因為DjangoAdmin使用的是ModelForm,它會將此作為一個欄位顯示]class UserType(models.Model): name = models.CharField(max_length=32)class News(models.Model): title = models.CharField(max_length=32) # Django幫我們建立第三張表favor favor = models.ManyToManyField("User") # DjangoAdmin裡面顯示2個欄位[title + favor多選框]# 自訂的第三張表,該樣本中引用的是many2many建立第三張表【admin中未註冊該類】class Favor(models.Model): new = models.ForeignKey("News", on_delete=True, related_name=‘u‘) user = models.ForeignKey("User", on_delete=True, related_name=‘n‘)
app01/admin.py
from django.contrib import admin# Register your models here.from app01 import modelsadmin.site.register(models.User)admin.site.register(models.News)admin.site.register(models.UserType)
頁面顯示;
初始化資料庫和admin使用者
python manage.py makemigrationspython manage.py migratepython manage.py createsuperuser
使用自訂的第三張表Favor的效果:
models.py
from django.db import modelsclass User(models.Model): id = models.AutoField(primary_key=True) # AutoField必須是主鍵,才能自訂該列 name = models.CharField(max_length=32) userType = models.ForeignKey("UserType", on_delete=True)# 1對多[無法用自訂,有約束關係] # 多對多[1. 自己建立第三張表 2. manytomany ] # 在DjangoAdmin裡面如果自己建立第三張表,則DjangoAdmin裡面不會有下拉框 # ManytoMany建立約束後,DjangoAdmin裡面會有下拉框[因為DjangoAdmin使用的是ModelForm,它會將此作為一個欄位顯示]class UserType(models.Model): name = models.CharField(max_length=32)class News(models.Model): title = models.CharField(max_length=32) # Django幫我們建立第三張表favor【這裡不引用它】 # favor = models.ManyToManyField("User") # 自訂的第三張表,【admin中註冊該類,引用自訂表格】class Favor(models.Model): new = models.ForeignKey("News", on_delete=True, related_name=‘u‘) user = models.ForeignKey("User", on_delete=True, related_name=‘n‘)
app01/admin.py
from django.contrib import admin# Register your models here.from app01 import modelsadmin.site.register(models.User)admin.site.register(models.News)admin.site.register(models.UserType)admin.site.register(models.Favor)
頁面顯示:
使用many2many + 自訂的第三張表:
更改了表單,需要重新寫入資料庫
注意:
1.因為我們使用的through_field()對Favor的部分欄位進行關聯,並未關聯全部,所以頁面是無法直接添加資料的。
2.我們使用through對自訂的Favor和News進行關聯後,是不能直接使用add(),remove()的操作方法的,
但是可以利用all(),filter()進行尋找操作。同時obj.favor.clear()也是可以用的...
models.py
from django.db import modelsclass User(models.Model): id = models.AutoField(primary_key=True) # AutoField必須是主鍵,才能自訂該列 name = models.CharField(max_length=32) userType = models.ForeignKey("UserType", on_delete=True)# 1對多[無法用自訂,有約束關係] # 多對多[1. 自己建立第三張表 2. manytomany ] # 在DjangoAdmin裡面如果自己建立第三張表,則DjangoAdmin裡面不會有下拉框 # ManytoMany建立約束後,DjangoAdmin裡面會有下拉框[因為DjangoAdmin使用的是ModelForm,它會將此作為一個欄位顯示]class UserType(models.Model): name = models.CharField(max_length=32)class News(models.Model): title = models.CharField(max_length=32) # Django幫我們建立第三張表且指向我們自訂的Favor表並添加指定的欄位 favor = models.ManyToManyField("User", through=‘Favor‘, through_fields=(‘new_obj‘, ‘user_obj‘))# 自訂的第三張表,【admin中註冊該類,引用自訂表格】class Favor(models.Model): new1 = models.ForeignKey("News", on_delete=True, related_name=‘u1‘) # 不引用該欄位 New_obj = models.ForeignKey("News", on_delete=True, related_name=‘u‘) user_obj = models.ForeignKey("User", on_delete=True, related_name=‘n‘)
app01/admin.py
from django.contrib import admin# Register your models here.from app01 import modelsadmin.site.register(models.User)admin.site.register(models.News)admin.site.register(models.UserType)admin.site.register(models.Favor)
頁面顯示:
初始化資料庫
python manage.py makemigrationspython manage.py migrate
問題解決:
問題現象:
問題定位:
Django幫建立了多對多的News.Favor和我們自訂的class Favor,此時2個是一個功能,所以系統提示我們查詢的時候名稱衝突了,添加一個查詢別名即可解決。
一對一操作:表和表的關聯
2種方法:
userProfile = models.ForeignKey("UserProfile", on_delete=True, unique=True) # 唯一索引
userDetail = models.OneToOneField("UserProfile", on_delete=True) # 一對一的另一種寫法
註:如果我們遇到了一個有很多列的表單時,可以拆分關鍵獨立一個表單,然後利用表和表之間一對一的關係進行關聯,可以減少sql查詢時候的時間
Models.py
from django.db import modelsclass User(models.Model): id = models.AutoField(primary_key=True) # AutoField必須是主鍵,才能自訂該列 name = models.CharField(max_length=32) userType = models.ForeignKey("UserType", on_delete=True) # 1對多[無法用自訂,有約束關係] userProfile = models.ForeignKey("UserProfile", on_delete=True, unique=True) # 一對一,唯一索引 userDetail = models.OneToOneField("UserProfile", on_delete=True) # 一對一的另一種寫法 # Sql最佳化: 長度固定的欄位放在最前面class UserProfile(models.Model): pwd = models.CharField(max_length=32)
更多參考:
Model操作;:http://www.cnblogs.com/wupeiqi/articles/6216618.html
Form操作; :http://www.cnblogs.com/wupeiqi/articles/6144178.html
Model操作;:http://www.cnblogs.com/wupeiqi/articles/6229414.html
Python學習---Model拾遺[1]180318