創(chuàng)建模型
在 Django 里寫一個(gè)數(shù)據(jù)庫驅(qū)動(dòng)的 Web 應(yīng)用的第一步是定義模型 - 也就是數(shù)據(jù)庫結(jié)構(gòu)設(shè)計(jì)和附加的其它元數(shù)據(jù)。
在這個(gè)簡單的投票應(yīng)用中,需要?jiǎng)?chuàng)建兩個(gè)模型:問題 Question 和選項(xiàng) Choice。Question 模型包括問題描述和發(fā)布時(shí)間。Choice 模型有兩個(gè)字段,選項(xiàng)描述和當(dāng)前得票數(shù)。每個(gè)選項(xiàng)屬于一個(gè)問題。
這些概念可以通過一個(gè)簡單的 Python 類來描述。按照下面的例子來編輯 polls/models.py 文件:
from django.db import models
class Question(models.Model):
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)
注:
1.每個(gè)模型有一些類變量,它們都表示模型里的一個(gè)數(shù)據(jù)庫字段。
2.我們使用 ForeignKey 定義了一個(gè)關(guān)系。這將告訴 Django,每個(gè) Choice 對象都關(guān)聯(lián)到一個(gè) Question 對象。Django 支持所有常用的數(shù)據(jù)庫關(guān)系:多對一ForeignKey 、多對多ManyToManyField和一對一OneToOneField。
3.如果是跨文件設(shè)置外鍵,首先引入模型,然后引入外鍵,如:
from django.db import models
from geography.models import ZipCode
class Restaurant(models.Model):
zip_code = models.ForeignKey(ZipCode,
on_delete=models.SET_NULL,
blank=True,
null=True)
激活模型
首先得把 polls 應(yīng)用安裝到我們的項(xiàng)目里,為了在我們的工程中包含這個(gè)應(yīng)用,我們需要在配置類 INSTALLED_APPS中添加設(shè)置:
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
現(xiàn)在你的 Django 項(xiàng)目會包含 polls 應(yīng)用。接著運(yùn)行下面的命令:
$ python manage.py makemigrations polls
通過運(yùn)行 makemigrations 命令,Django 會檢測你對模型文件的修改(在這種情況下,你已經(jīng)取得了新的),并且把修改的部分儲存為一次 遷移。
現(xiàn)在,再次運(yùn)行 migrate 命令,在數(shù)據(jù)庫里創(chuàng)建新定義的模型的數(shù)據(jù)表:
$ python manage.py migrate
這個(gè) migrate 命令選中所有還沒有執(zhí)行過的遷移(Django 通過在數(shù)據(jù)庫中創(chuàng)建一個(gè)特殊的表 django_migrations 來跟蹤執(zhí)行過哪些遷移)并應(yīng)用在數(shù)據(jù)庫上 - 也就是將你對模型的更改同步到數(shù)據(jù)庫結(jié)構(gòu)上。
遷移是非常強(qiáng)大的功能,它能讓你在開發(fā)過程中持續(xù)的改變數(shù)據(jù)庫結(jié)構(gòu)而不需要重新刪除和創(chuàng)建表 - 它專注于使數(shù)據(jù)庫平滑升級而不會丟失數(shù)據(jù)。我們會在后面的教程中更加深入的學(xué)習(xí)這部分內(nèi)容,現(xiàn)在,你只需要記住,改變模型需要這三步:
1.編輯 models.py 文件,改變模型。
2.運(yùn)行 python manage.py makemigrations 為模型的改變生成遷移文件。
3.運(yùn)行 python manage.py migrate 來應(yīng)用數(shù)據(jù)庫遷移。
Field options
常用字段
null
If True, Django will store empty values as NULL in the database.
Default is False.
blank
If True, the field is allowed to be blank. Default is False.
Note that this is different than null.
null is purely database-related, whereas
blank is validation-related. If a field has
blank=True, form validation will
allow entry of an empty value. If a field has blank=False, the field will be required.
choices
An iterable (e.g., a list or tuple) of 2-tuples to use as choices for
this field. If this is given, the default form widget will be a select box
instead of the standard text field and will limit choices to the choices
given.
A choices list looks like this:
YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
)
The first element in each tuple is the value that will be stored in the
database. The second element is displayed by the field's form widget.
Given a model instance, the display value for a field with choices can
be accessed using the get_FOO_display()
method. For example:
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display()
'Large'
default
The default value for the field. This can be a value or a callable
object. If callable it will be called every time a new object is
created.
help_text
Extra "help" text to be displayed with the form widget. It's useful for
documentation even if your field isn't used on a form.
primary_key
If True, this field is the primary key for the model.
If you don't specify primary_key=True for
any fields in your model, Django will automatically add an
IntegerField to hold the primary key, so you don't need to set
primary_key=True on any of your fields
unless you want to override the default primary-key behavior. For more,
see Automatic primary key fields.
The primary key field is read-only. If you change the value of the primary
key on an existing object and then save it, a new object will be created
alongside the old one. For example:
from django.db import models
class Fruit(models.Model):
name = models.CharField(max_length=100, primary_key=True)
>>> fruit = Fruit.objects.create(name='Apple')
>>> fruit.name = 'Pear'
>>> fruit.save()
>>> Fruit.objects.values_list('name', flat=True)
<QuerySet ['Apple', 'Pear']>
unique
If True, this field must be unique throughout the table.