- Learning Website Development with Django
- Ayman Hourieh
- 2107字
- 2021-07-02 11:41:17
Models: Designing an Initial Database Schema
Almost every Web 2.0 application requires a database to store and manage its data. The database engine is a fundamental component of web development nowadays. Web applications offer the user a UI to enter and manage their data, and use a database engine behind the scenes to manage this data.
We will chose the database engine that configured our database settings in the previous chapter. In this section, we will make use of the database to store and manage user accounts and bookmarks.
If you are used to dealing with the database directly through SQL queries, then you may find Django's approach to database access a bit different. Loosely speaking, Django abstracts access to database tables through Python classes. To store, manipulate and retrieve objects from the database, the developer uses a Python-based API. In order to do this, SQL knowledge is useful but not required.
This technique is best explained by example. For our bookmarking application, we need to store three types of data in the database:
- Users (ID, username, password, email)
- Links (ID, URL)
- Bookmarks (ID, title, user_id, link_id)
Each user will have their own entry in the Users table. This entry stores the username, password and email. Similarly, each link will have a corresponding entry in the links table. We will only store the link's URL for now.
As for the Bookmarks table, you can think of it as the joining table between Users and Links. When a user adds a bookmark, an entry for the bookmark's URL is added to the links table if it doesn't already exist, and then a joining entry is added to the Bookmarks table. This entry connects the user with the link, and stores the title that the user entered for their bookmark.
To convert this table design into Python code, we need to edit models.py
in bookmarks
and enter the details of each object type. models.py
is the file where database models are stored, and it only contains an import
line when it's created by manage.py
startapp
.
The Link Data Model
Let's start by creating the data model for the Links table, because it's the simplest one. Open bookmarks/models.py
in your editor and type the following code:
from django.db import models class Link(models.Model): url = models.URLField(unique=True)
Going through the code line by line, we learn the following:
- The
models
package contains classes that are required to define models, so it is imported first. - We define a class named
Link
. This class inherits frommodels.Model
, which is the base class for all models. The class contains one field namedurl
, and it's of the typemodels.URLField
. This field must be unique.
models.URLField
is one of many field types provided by Django. Below is a partial table of these types:

To use this model, we first need to activate it in our Django project. This is done by editing settings.py
, looking for the INSTALLED_APPS
variable, and adding our application name (django_bookmarks.bookmarks
) to it:
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django_bookmarks.bookmarks', )
Now, issue the following command to create a table for the Link data model in the database:
$ python manage.py syncdb
You may remember that we used this command in the previous chapter to create Django's own administrative tables. Whenever you add a data model, you need to issue this command in order to create its table in the database.
If you are familiar with SQL, you can examine the SQL query generated by Django by running the following command:
$ python manage.py sql bookmarks
The output from this command may differ slightly depending on your database engine. For SQLite, it should look similar to the following:
BEGIN; CREATE TABLE "bookmarks_link" ( "id" integer NOT NULL PRIMARY KEY, "url" varchar(200) NOT NULL UNIQUE ); COMMIT;
What has happened here? Django analyzed our Link model, which is a regular Python class, and generated an SQL CREATE
statement for a database table named bookmarks_link
; this table will store instances of the Link class. Notice that Django automatically added an id
field to the table. This field is the primary key of the table and can be used to identify links and connect them to bookmarks.
The power of Django's Python database API does not stop at creating tables. We can use it to create entries in the table, to modify entries, to search and browse the table contents, among many other things. To explore the API, we will use the Python interactive console. To launch the console use this command:
$ python manage.py shell
This shell differs from the standard Python shell in two ways. Firstly, the project path is added to sys.path
, which simplifies importing modules from our project. Secondly, a special environment variable is created to hold the path to our settings.py
. So whenever you need a Python shell to interact with your project, use the above command.
Now import the contents of the models module:
>>> from bookmarks.models import *
To add a new link, create a new instance of the Link
class and call the save
method on it:
>>> link1 = Link(url='http://www.packtpub.com/') >>> link1.save() >>> link2 = Link(url='http://www.example.com/') >>> link2.save()
Calling the save
method is required to store the object in the database. Before that, the object exists in memory only, and it will be lost if you close the console. However, when you call save
, the object is stored in the database.
Table fields become attributes of objects. To examine and change a link's URL, type the following:
>>> link2.url 'http://www.example.com/' >>> link2.url = 'http://www.google.com/' >>> link2.save()
To get a list of all available Link objects, type the following:
>>> links = Link.objects.all() >>> for link in links: ... print link.url ... http://www.packtpub.com/ http://www.google.com/
To get an object by ID, type the following:
>>> Link.objects.get(id=1) <Link: Link object>
Finally, to delete a link, use the following:
>>> link2.delete() >>> Link.objects.count() 1
And output of 1 indicates that there is now only one remaining link. Notice that we were able to do all of the above without needing a single SQL statement. Django's model API can do a lot more; it covers all the tasks commonly done through SQL. Actually, the above method calls are converted to SQL statements, and the results of the statements are returned. The benefits of this approach are numerous:
- You don't have to learn another language to access the database. You already know Python and how use it to write views, so it's obviously a benefit if you can also use it to access the database.
- Django transparently handles the conversion between Python objects and table rows. You only work with Python objects, and Django automatically stores and retrieves them from the database for you.
- You don't have to worry about any special SQL syntax for different database engines, especially if you have to switch from one engine to another. The Django model API is the same no matter what engine you use, and it takes care of the differences for you.
The User Data Model
Now that you are comfortable with the concept of data models, let's move to the User
object. Fortunately for us, management of user accounts is so common that Django comes with a user model ready for us to use. This model contains fields that are often associated with user accounts, such as username, password and email and so on. The model is called User
and it's located in the django.contrib.auth.models
package.
To explore the contents of this model, open the interactive console and type the following:
>>> from django.contrib.auth.models import User >>> User.objects.all() [<User: ayman>]
We can see that the table represented by this model already contains a user. Remember when we configured the database in the previous chapter? We had to create the superuser account, and Django stored this user in the table of the User model.
You can examine the fields of User
objects by using the dir
function:
>>> user = User.objects.get(id=1) >>> dir(user)
You will get a very long list of attributes. Among them you will find the username, email address and password. Good news! This model fulfills our needs. Django provides all the necessary attributes for our user objects, and we can use directly use the User
model directly without any extra code.
The Bookmark Data Model
Only one model remains, the Bookmark
model. When we examined it earlier, we realized that a bookmark connects a user to a link. A bookmark belongs to one user and one link. However, one user may have many bookmarks, and one link may be bookmarked by many users. In database language we say there is a many-to-many relationship between users and links. However, there is no way to actually represent a many-to-many relationship such as this one using a standard database system. In our particular case, we will invent the concept of a bookmark to break up this many-to-many relationship into its constituent one-to-many relationships.
The first of these is the one-to-many relationship between the user and their bookmarks. One user can have many bookmarks, but each bookmark is associated with only one user. That is to say, each user can bookmark a particular link once.
The second of these is the one-to-many relationship between a link and its bookmarks. One link can have many bookmarks associated with it if multiple users have bookmarked it, but each bookmark is associated with only one link.
Now that we have two separate one-to-many relationships, it is possible to represent all of this in a database system. To do so, we create a third table, the bookmarks table, which connects the user table and the links table. Each row in the bookmarks table has a reference to a row in the users table (that is to a particular user) and a reference to the links table (that is to a particular link). In SQL, these references to rows in "foreign" tables are known as foreign keys, but instead of working with SQL to define tables and foreign keys, we will use the Django model API to write a data model for the bookmarks.
The following code listing contains the Bookmark data model. You should insert it into bookmarks/models.py
. For those who are new to relational databases and SQL, this section may seem a little obscure at first. However, it will all make more sense when you see it in action. Here is the code for the Bookmark data model:
from django.contrib.auth.models import User class Bookmark(models.Model): title = models.CharField(maxlength=200) user = models.ForeignKey(User) link = models.ForeignKey(Link)
We first import the User
class in order to refer to it in the Bookmark model. Next, we define a class for the Bookmark model as we did with Link
. The new model contains a text field called title
, and two foreign keys that refer back to the User
and Link
models.
Tip
Code Snippets and import statements
Python conventions suggest putting import
statements at the beginning of the source file. When adding code to an existing file, there will be new import
statements at the beginning of the new code snippet, but you are recommended to move these statements to the beginning of the file.
After you enter the model's code into models.py
, you need to run manage.py
syncdb
in order to create its corresponding table.
Let's examine the SQL query generated by Django to see how it automatically handles foreign keys. Again, issue the following command:
$ python manage.py sql bookmarks
And you will see the CREATE
statement for the Bookmark
data model:
BEGIN; CREATE TABLE "bookmarks_bookmark" ( "id" integer NOT NULL PRIMARY KEY, "title" varchar(200) NOT NULL, "user_id" integer NOT NULL REFERENCES "auth_user" ("id"), "link_id" integer NOT NULL REFERENCES "bookmarks_link" ("id"), ); CREATE TABLE "bookmarks_link" ( "id" integer NOT NULL PRIMARY KEY, "url" varchar(200) NOT NULL UNIQUE ); COMMIT;
Notice how Django appended _id
to the table name to create foreign key fields and generated the necessary SQL for expressing one-to-many relations.
Now that the data models are ready, we have the facilities to store and manage our data. Django offers an elegant and straightforward Python API to store Python objects in the database, thus sparing the developer the burden of working with SQL and converting between SQL and Python types and idioms.
Next, we will learn about another major Django component, the template system. We will use it to simplify working with page creation, and then make use of all the information we learned in this chapter to create bookmark listing pages for users.
- Flash CC中文版動畫設(shè)計與制作/微課堂學(xué)電腦
- Hadoop核心技術(shù)
- UG NX 12.0實例寶典
- 我為PS狂 Photoshop照片處理一分鐘秘笈
- After Effects CC 2019 影視后期特效合成案例教程
- ADOBE FLASH PROFESSIONAL CS6 標(biāo)準(zhǔn)培訓(xùn)教材
- Cinema 4D完全實戰(zhàn)技術(shù)手冊
- Android從入門到精通
- Adobe創(chuàng)意大學(xué)Illustrator CS5 產(chǎn)品專家認證標(biāo)準(zhǔn)教材
- 會聲會影視頻編輯實戰(zhàn)秘技250招
- Word-Excel-PowerPoint 2010三合一辦公應(yīng)用實戰(zhàn)從入門到精通(超值版)
- 中文版3ds Max 2016/VRay效果圖制作實戰(zhàn)基礎(chǔ)教程(全彩版)
- 3ds Max影視動畫角色設(shè)計技法教程
- 藝術(shù)二維碼設(shè)計與制作完全攻略 PHOTOSHOP+ILLUSTRATOR+FLASH
- Adobe Flash CS4 動畫設(shè)計與制作標(biāo)準(zhǔn)實訓(xùn)教程