上一节我们建立了一个最基本的工程项目,这一节我们要在里面添加应用,填充数据库,并且能在后台管理界面看到他。
创建应用
在django中有两个概念需要弄清楚。一个是工程(project)的概念,一个是应用(application)的概念。它们的关系是:一个工程中包含多个应用。每个应用都是独立的,应用通过setting.py注册到工程中来就可以使用了。而一个应用也可以被不同工程复用,这大大提高了开发效率。
进入虚拟环境就不多说了,还是在第一级mysite目录内,执行下面命令:
(myvenv) $ python manage.py startapp blog
这就建立了一个名为blog的应用。现在的目录结构如下:
mysite
├── mysite
| __init__.py
| settings.py
| urls.py
| wsgi.py
├── manage.py
├── db.sqlite3
└── blog
├── migrations
| __init__.py
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── tests.py
└── views.py
打开settings.py,添加blog应用:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', #新增加的应用
]
到此,一个应用已经建立并加入工程了。
创建模型
上一节中我们曾说django采用了MVC设计模式,这里的M就是模型models。我理解模型就是规定了网页数据结构的类型,比如对于一个博客来说,其基本组成就是一篇篇文章,而文章包含了标题、作者、标签、正文、创建时间和发布时间等元素。据此我们在models.py中建立如下Article模型:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Article(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=200)
category = models.CharField(max_length=50, blank=True)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
我们引用了django.db内的models,定义了我们的模型,并建立了publish方法来发布文章。````str或者
unicode```告诉系统使用title字段来表示这个Article的对象。模型内的几种类型解释如下:
-
CharField
:普通的文本,用来存储字符串,max_length设置最大长度 -
TextField
:长文本,存储大量文本 -
DateTimeField
:日期时间类型,default=timezone.nowb表示默认时间就是当前系统时间 -
ForeignKey
:外键类型
数据库生成表
我们虽然在models内建立了数据模型,但是数据库并不知道我们的数据到底是怎么组成的,有什么特点,因此还要同步数据库,在数据库内生成表。每次我们建立一个新的模型,都要在数据库内添加对应的表。
第一步是先让django感知到我们刚刚已经创建了一个新的模型:
(myvenv) $ python manage.py makemigrations blog
输出如下:
Migrations for 'blog':
blog\migrations\0001_initial.py:
- Create model Article
第二步是让django帮我们执行这些文件:
(myvenv) $ python manage.py migrate blog
输出如下:
Operations to perform:
Apply all migrations: blog
Running migrations:
Applying blog.0001_initial... OK
数据库内就有Article这张表了。
对象关系映射ORM
对象关系映射ORM提供了概念性的、易于理解的模型化数据的方法。ORM方法论基于三个核心原则:
- 简单:以最基本的形式建模数据。
- 传达性:数据库结构被任何人都能理解的语言文档化。
- 精确性:基于数据模型创建正确标准化了的结构。
ORM一定程度上简化了数据库操作。想学习ORM框架的更多知识请自行Google。下面我们看看django的ORM是怎样和数据库打交道的。
进入Django Shell
进入django shell与进入Python shell十分相似:
(myvenv) $ python manage.py shell
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
添加用户和文章
我们先查看现在数据库内的文章:
>>> from blog.models import Article
>>> Article.objects.all()
这里的QuerySet是Article模型的对象列表,用来从数据库中读取数据,过滤和排序等等,现在列表当然为空。
模型Article里有author = models.ForeignKey(User)
,所以在添加文章前,我们先建立一个用户User。
>>> from django.contrib.auth.models import User
>>> User.objects.create(username='yuan')
>>> User.objects.all()
]>
然后添加文章:
>>> user = User.objects.get(username='yuan')
>>> Article.objects.create(author = user, title = 'Sample title', category = 'test', text = 'Test')
>>> Article.objects.all()
]>
可见我们已经添加了一篇作者是yuan,标题为Sample title,标签是test,内容是Test的博客。这里用标题代表了一篇文章,这是不是和models里的__str__
一致?用这种方法多添加几篇文章。
文章的删、改、查
我们刚才使用Article.objects.all()
获取全部文章,还可以用get
获取和filter
过滤文章,可以在filter
括号内使用多个过滤条件,用逗号隔开:
>>> Article.objects.get(id = 1)
>>> Article.objects.filter(author=user)
, , ]>
>>> Article.objects.filter(title__contains='2')
]>
>>> Article.objects.filter(published_date__isnull=False)
我们最后查到了一张空表,这是因为所有文章都没有设定发布时间。可以利用Article内的方法publish
设定它:
>>> fir = Article.objects.get(id=1)
>>> fir.publish()
>>> Article.objects.filter(published_date__isnull=False)
]>
对于其他内容,也可以修改:
>>> sec = Article.objects.get(id=2)
>>> sec.text
'Test2'
>>> sec.text = 'this is the second text'
>>> sec.text
'this is the second text'
当然,也可以删除文章:
>>> thr = Article.objects.get(id=3)
>>> thr.delete()
(1, {'blog.Article': 1})
>>> Article.objects.all()
, ]>
排序
可以按照某关键字排序,关键字前加“-”表示反序:
>>> Article.objects.order_by('created_date')
, ]>
>>> Article.objects.order_by('-created_date')
, ]>
最后exit()退出即可。
>>> exit()
admin后台管理
除了在django控制台对文章进行操作,更多的是在admin后台管理界面进行管理。下一步就是实现这个功能。
查看mysite\mysite\settings.py:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin', # 默认添加admin后台管理功能
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
以及mysite\mysite\urls.py也默认添加进入后台的url:
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
在mysite\blog\admin.py注册对应的模型:
from django.contrib import admin
from .models import Article
admin.site.register(Article)
这里的.models
使用了Python3的相对导入,指向和admin.py同一目录下的models.py。
接下来只需要注册一个管理员账号:
(myvenv) $ python manage.py createsuperuser
Username (leave blank to use 'yukim'): admin
Email address:
Password:
Password (again):
Superuser created successfully.
两个password项的输入会隐藏起来看不见,输入密码回车即可。账号创建完毕!
启动服务器:
(myvenv) $ python manage.py runserver
根据url设置,打开链接:http://127.0.0.1:8000/admin/
输入账号密码:
进入管理界面:
就可以在里面对文章直接进行增删改查:
多添加几篇文章,并确保至少有两篇有Publish date,防止后续出错。
关于admin界面的更多使用,可以参照官方文档: admin
也可以用bootstrap等第三方插件美化界面,这里就不详细介绍了。
2016.10.20