?
成都地區(qū)優(yōu)秀IDC服務(wù)器托管提供商(創(chuàng)新互聯(lián)).為客戶提供專業(yè)的成都西信服務(wù)器托管,四川各地服務(wù)器托管,成都西信服務(wù)器托管、多線服務(wù)器托管.托管咨詢專線:13518219792
目錄
model 1
model:...2
常用Field types:...5
Relationship fields.5
Field options:...6
Meta options:...6
重寫save()方法:...7
模型繼承:...7
抽象基類:...7
多表繼承:...8
代理繼承:...9
多重繼承:...10
?
?
?
?
模型的價值在于定義數(shù)據(jù)模型,使用py代碼ORM形式操作數(shù)據(jù)庫;
?
mysite/mysite/settings.py?? #只有在settings.py中激活app才能使用models
INSTALLED_APPS = [
??? 'publish.apps.PublishConfig',
??? 'bootstrap3',
??? 'books.apps.BooksConfig',
??? 'polls.apps.PollsConfig',
??? 'django.contrib.admin',
??? 'django.contrib.auth',
??? 'django.contrib.contenttypes',
??? 'django.contrib.sessions',
??? 'django.contrib.messages',
??? 'django.contrib.staticfiles',
]
?
?
支持sqlite、MySQL、postgresql、oracle;
py3.5以上版本,不支持MySQLdb驅(qū)動;
可用pymysql,py寫的;
可用mysqlclient,c寫的,速度快,fork的MySQLdb,官方推薦;
?
ORM,用py的方法、數(shù)據(jù)結(jié)構(gòu),來訪問db,可兼容不同的DB;
?
一個class代表一張表,多對多會產(chǎn)生額外一張關(guān)系表;
默認(rèn)pk為id,也可自定義pk;
表名默認(rèn)為$APP_NAME$CLASS_NAME.lower(),表名小寫(跨平臺支持),可重寫;
?
models migrations:
定義好models.py需應(yīng)用到db,django為了能跟蹤表結(jié)構(gòu)的變化,增加了migration版本控制功能,如果沒有該功能,需手動編寫表結(jié)構(gòu)變化的語句,重新導(dǎo)入數(shù)據(jù);
先makemigrations再migrate;
?
models CRUD:
增:
q = Question(**kwargs)?? #方式1,實例化,Model(kwargs).save()
q.save()
?
q = Question.objects.create(**kwargs)?? #方式2,用管理器形式,Model.objects.create(**kwargs)
?
刪:
q = Question.objects.get(id=1)?? #QuerySet.delete()
q.delete()?? #object.delete()
?
Question.objects.filter(id=1).delete()
Question.objects.all().delete()
?
改:
q = Question.objects.get(id=1)
q.question_text = 'some text'?? #object.attr = value.object.save()
q.save()
?
Question.objects.filter(id=1).update(question_text='why ?')?? #QuerySet.update(**kwargs)
?
查:
Question.objects.all()?? #Model.objects.all(kwargs),Model.objects.filter(kwargs),Model.objects.get(**kwargs)
Question.objects.filter(question_text="what's up?")?? #objects,model默認(rèn)的manager管理器
Question.objects.get(id=1)
latest_question_list = Question.objects.order_by('-pub_date')[:3]?? #默認(rèn)升序,加上-為倒序
?
for p in Person.objects.raw('select * from myapp_person'):?? #執(zhí)行原生sql
???????? print(p)
?
注:
>>> from django.utils import timezone
>>> import datetime
>>> timezone.now()?? #比datetime.datetime.now()多了時區(qū),在頁面展示時,django內(nèi)部會轉(zhuǎn)為適合用戶所在的時區(qū)
datetime.datetime(2019, 1, 2, 7, 2, 18, 244920, tzinfo=<UTC>)
>>> datetime.datetime.now()
datetime.datetime(2019, 1, 2, 15, 2, 32, 837755)
?
models中方法:
def __str__(self):
???????? return self.question_text
def was_published_recently(self):
???????? return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
?
?
mysite/mysite/settings.py
DATABASES = {
??? 'default': {
??????? 'ENGINE': 'django.db.backends.sqlite3',
??????? 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
??? }
}
?
?
mysite/polls/models.py
from django.db import models
?
class Question(models.Model):?? #一個class代表一張表,多對多會產(chǎn)生額外一張關(guān)系表;默認(rèn)pk為id,也可自定義pk;表名默認(rèn)為$APP_NAME$CLASS_NAME.lower(),可重寫
??? question_text = models.CharField(max_length=200)
??? pub_date = models.DateTimeField('date published')
?
class Choice(models.Model):
??? question = models.ForeignKey(Question, on_delete=models.CASCADE)
??? choice_text = models.CharField(max_length=200)
??? votes = models.IntegerField(default=0)
?
(webproject) C:\webproject\mysite>python manage.py makemigrations?? #生成遷移記錄,先makemigrations才能migrate
(webproject) C:\webproject\mysite>python manage.py migrate?? #應(yīng)用到db
(webproject) C:\webproject\mysite>sqlite3 db.sqlite3
sqlite> .tables
auth_group???????????????? ?django_admin_log
auth_group_permissions????? django_content_type
auth_permission???????????? django_migrations
auth_user?????????????????? django_session
auth_user_groups??????????? polls_choice
auth_user_user_permissions? polls_question
sqlite> .quit
?
(webproject) C:\webproject\mysite>dir polls\migrations\
?驅(qū)動器 C 中的卷是 OS
?卷的序列號是 000B-5D26
C:\webproject\mysite\polls\migrations 的目錄
2019/01/02? 14:24??? <DIR>????????? .
2019/01/02? 14:24??? <DIR>????????? ..
2019/01/02? 14:24???????????? 1,266 0001_initial.py
2019/01/02? 11:29???????????????? 0 __init__.py
2019/01/02? 14:25??? <DIR>????????? __pycache__
?????????????? 2 個文件????????? 1,266 字節(jié)
?????????????? 3 個目錄 77,168,365,568 可用字節(jié)
(webproject) C:\webproject\mysite>python manage.py sqlmigrate polls 0001_initial?? #查看sql語句是否是指定要求的
?
(webproject) C:\webproject\mysite>python manage.py shell??#進(jìn)入交互式命令行
>>> from django.utils import timezone
>>> from polls.models import Question,Choice
>>> q = Question(question_text="what's new", pub_date=timezone.now())
>>> q.save()
>>> q.id
1
>>> q.pk?? #django默認(rèn)會增加id為pk
1
>>> q.question_text
"what's new"
>>> q.pub_date
datetime.datetime(2019, 1, 2, 6, 49, 16, 612213, tzinfo=<UTC>)
?
>>> from polls.models import Question,Choice
>>> from django.utils import timezone
>>> q = Question.objects.create(question_text="how are you?", pub_date=timezone.now())
>>> q = Question.objects.create(question_text="what's the weather?", pub_date=timezone.now())
>>> q = Question.objects.create(question_text="fuck you!", pub_date=timezone.now())
>>> q
<Question: fuck you!>
>>> q.was_published_recently()
True
>>> d = timezone.now() - timezone.timedelta(days=2)
>>> q.pub_date = d
>>> q.save()
>>> q.was_published_recently()
False
?
?
?
https://docs.djangoproject.com/en/2.1/ref/models/fields/#choices
?
name = models.CharField(max_length=30)?? #實例化時是py中的數(shù)據(jù)類型
num = models.IntegerField()
website = models.URLField()
email = models.EmailField()
models.AutoField()?? #定義AI或PK時用
models.BooleanField()
models.TextField()
models.DateField()?? #接收py中datetime對象,自動轉(zhuǎn)為sql中的數(shù)據(jù)結(jié)構(gòu)
models.PositiveIntegerField()?? #正數(shù)
?
?
關(guān)系:
authors = models.ManyToManyField(Author)?? #many-to-many,如用戶和組,博客項目中文章和標(biāo)簽;
publisher = models.ForeignKey(Publisher)?? #many-to-one,如外鍵,1個問題有多個選項,1個選項只能屬1個問題;如汽車-工廠;
moodels.OneToOneField(<field-name>)?? #one-to-one,如Restaurant餐館和place地點,如丈夫-妻子;
?
?
field參數(shù):
null?? #default is False,mysql中空值用null表示,不能用''(''表示字符串的空串)
blank
choices?? #同sqlalchemy中enum,展示在前端為不能讓用戶自己定義,而是在下拉列表中選擇
default
help_text?? #sql中的comment;form中的備注信息
primary_key?? #默認(rèn)自動加id作為主鍵,若顯式指定將不會有默認(rèn)id主鍵
unique
verbose_name?? #若有定義,在form中將把此處定義的值大寫,中間的_改為空格,顯示為form中的label
?
例:
class Group(models.Model):
??? pass
?
class User(models.Model):
??? groups = models.ManyToManyField(Group)
?
例:
class Place(models.Model):
??? name = models.CharField(max_length=50)
??? address = models.CharField(max_length=80)
?
class Restaurant(models.Model):
??? place = models.OneToOneField(Place, primary_key=True)
??? servers_hot_dogs = models.BooleanField(default=False)
??? servers_pizza = models.BooleanField(default=False)
?
例:
class Manufacturer(models.Model):
??? pass
?
class Car(models.Model):
??? manufacturer = models.ForeignKey(Manufacturer)
?
?
?
元編程,改變之前表中定義的元數(shù)據(jù)信息;
?
abstract?? #abstract = True,this model will be an abstract base class,聲明是基類,數(shù)據(jù)庫將不會建此表
db_table?? #db_table = 'music_album'指定表名
get_latest_by?? #get_latest_by = 'order_date'指定此字段按升序,get_latest_by = ['-priority','order_date']指定priority按降序,order_date按升序;查詢時Question.objects.latest()要先定義get_latest_by根據(jù)哪個字段走
ordering?? #對象的默認(rèn)順序,獲取對象列表,默認(rèn)升序,前綴-降序,前綴?隨機randomly,ordering = ['pub_date'],ordering = ['-pub_date', 'author']
unique_together?? #聯(lián)合唯一鍵,unique_together('driver','restaurant')
indexes?? #聯(lián)合索引
managed
verbose_name?? #admin后臺中顯示的名字
?
?
?
from django.db import models
?
class Blog(models.Model):
???????? name = models.CharField(max_length=100)
???????? tagline = models.TextField()
?
???????? def save(self, *args, **kwargs):
?????????????????? do_something()
?????????????????? super(Blog, self).save(*args, **kwargs)?? #import,call the real save() method,一定要調(diào)用父類的save(),否則不會保存到數(shù)據(jù)庫
?????????????????? do_something()
?
?
?
若只使用父類中的信息,用繼承,而不用在子類模型中重復(fù)輸入與父類相同的那些字段;
抽象出的基類不會單獨使用;
使用Meta option,abstract = True,聲明是基類,數(shù)據(jù)庫將不會建此表;.
若子類不實現(xiàn)Meta,默認(rèn)會繼承;
例:
class CommonInfo(models.Model):
??? name = models.CharField(max_length=100)
??? age = models.PositiveIntegerField()
?
??? class Meta:
??????? abstract = True
??????? ordering = ['name']
?
class Student(CommonInfo):
??? home_group = models.CharField(max_length=5)
?
??? class Meta:?? #若子類不實現(xiàn)Meta,默認(rèn)會繼承
??????? db_table = 'student_info'
?
?
若繼承一個已存在的模型且想讓每個模型都有它自己的數(shù)據(jù)庫表,應(yīng)使用多表繼承;
每一個層級下的每個model都是一個真正意義上完整的model,每個model都有專屬的數(shù)據(jù)庫表,都可查詢和創(chuàng)建數(shù)據(jù)庫表;
繼承關(guān)系在子model和它的每個父類之間都添加一個鏈接,自動創(chuàng)建OneToOneField;
父類Place中未在Meta中定義abstract=True,子類Restaurant在查看表結(jié)構(gòu)時,不會繼承父類的name和address,而是主鍵place_str_id上有指針指向父類中的字段;
子類繼承父類,子類創(chuàng)建的記錄,父類中會自動有;
例:
class Place(models.Model):
??? name = models.CharField(max_length=50)
??? address = models.CharField(max_length=80)
?
class Restaurant(Place):
??? servers_hot_dogs = models.BooleanField(default=False)
??? servers_pizza = models.BooleanField(default=False)
?
sqlite> .schema publish_place
CREATE TABLE IF NOT EXISTS "publish_place" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(50) NOT NULL, "address" varchar(80) NOT NULL);
sqlite> .schema publish_restaurant
CREATE TABLE IF NOT EXISTS "publish_restaurant" ("place_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "publish_place" ("id"), "servers_hot_dogs" bool NOT NU
LL, "servers_pizza" bool NOT NULL);
?
>>> from publish.models import Place,Restaurant
>>> Place.objects.create(name='tsinghua', address='zhongguancun')
<Place: Place object>
>>> Restaurant.objects.create(name='jia',address='bj',servers_hot_dogs=True,servers_pizza=False)
<Restaurant: Restaurant object>
>>> p0 = Place.objects.get(name='tsinghua')
>>> p1 = Place.objects.get(name='jia')
>>> p2 = Restaurant.objects.get(name='tsinghua')?? #X
……"C:\Users\Administrator\py_env\webproject\lib\site-packages\django\db\models\query.py", line 379, in get
? ??self.model._meta.object_name
publish.models.DoesNotExist: Restaurant matching query does not exist.
>>> p3 = Restaurant.objects.get(name='jia')
>>> p0.restaurant?? #X
……"C:\Users\Administrator\py_env\webproject\lib\site-packages\django\db\models\fields\related_descriptors.py", line 404, in __get__
??? self.related.get_accessor_name()
django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist: Place has no restaurant.
>>> p1.restaurant
<Restaurant: Restaurant object>
?
?
使用多表繼承時,model的每個子類都會創(chuàng)建一張新數(shù)據(jù)表,因為子類需要一個空間來存儲不包含在基類中的字段數(shù)據(jù)(如servers_hot_dogs、servers_pizza),有時只想更改model在py層的行為實現(xiàn),如改默認(rèn)的manager,或添加一個新方法,這時用代理繼承;
為原始模型創(chuàng)建一個代理,可創(chuàng)建、刪除、更新代理model的實例,而且所有的數(shù)據(jù)都可象使用原始model一樣被保存;
不同之處在于,可在代理model中改變默認(rèn)的排序設(shè)置和默認(rèn)的manager,更不會對原始model產(chǎn)生影響;
使用Meta option,proxy = True,對代理model的聲明;
MyPerson只是一個代理,數(shù)據(jù)庫中不會創(chuàng)建該表,MyPerson類和其父類Person操作同一個數(shù)據(jù)表,特別之處,Person的實例也可通過MyPerson訪問;
例:
class Person(models.Model):
??? first_name = models.CharField(max_length=30)
??? last_name = models.CharField(max_length=30)
?
class MyPerson(Person):
??? class Meta:
??????? proxy = True
?
??? def do_something(self):
??????? pass
?
>>> from publish.models import Person,MyPerson
>>> p = Person.objects.create(first_name='foobar')
>>> MyPerson.objects.get(first_name='foobar')
<MyPerson: MyPerson object>
?
?
同多表繼承,會自動添加2個OneToOneField,注意,2個基類的默認(rèn)id要重新命名,否則添加OneToOneField會有問題,也不允許子類重寫父類字段;
例:
class Article(models.Model):
??? article_id = models.AutoField(primary_key=True)
?
class Book2(models.Model):
??? book_id = models.AutoField(primary_key=True)
?
class Book2Review(Book, Article):
??? pass
?
?
?
?
?
分享名稱:97django_model
標(biāo)題來源:http://www.rwnh.cn/article30/gcgpso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、ChatGPT、服務(wù)器托管、網(wǎng)站導(dǎo)航、電子商務(wù)、域名注冊
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)