模型设计
从我们的页面设计来看,我们的博客需要有标题、作者、正文及发布的时间等基本的元素。同时,一个博客还会隶属于一个分类,并可能包含一个或多个标签。博客也可以有一个或多个评论,评论中要记录评论者的名称、及评论内容。
from django.db import models
class Category(models.Model):
"分类"
name = models.CharField(max_length=50)
class Tag(models.Model):
"标签"
name = models.CharField(max_length=50)
class Blog(models.Model):
"博客"
title = models.CharField(max_length=50)
author = models.CharField(max_length=16)
content = models.TextField()
created = models.DateTimeField( auto_now_add=True)
category = models.ForeignKey(Category)
tags = models.ManyToManyField(Tag, blank=True)
Catrgory类、Tag类、Blog类都继承自Model类。CharField定义name、title、author属性为字符串,max_length定义字符串的长度,blank设置true表示可以为空。因为文章内容会比较大,所以选择TextField属性。存储时间字段用DateTimeField属性定义,auto_now_add设置true表示自动设置对象增加时间。
一篇文章只能有一个类别,但可以有多个不同的标签。一个类别下可以有多个文章,一个标签下也可以有多篇文章。因此,ForeignKey定义类别与文章是一对多的关系,ManyToField定义标签和文章是多对多的关系。
模型只是利用 Django 提供的 ORM 完成对实际表结构的映射,因此在完成模型定义后,我们需要将其真正同步到实际的数据库中去。该操作需要分成两步,第一步是生成 migrations:
(env) $: python manage.py makemigrations blogpost
Migrations for 'blogpost':
blogpost/migrations/0001_initial.py
- Create model Blog
- Create model Category
- Create model Tag
- Add field category to blog
- Add field tags to blog
生成如下文件:
migrations/
├── 0001_initial.py
├── __init__.py
第二步执行migrate命名与数据库同步:
(env)$:python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blogpost, contenttypes, sessions
Running migrations:
Applying blogpost.0001_initial... OK
最后一行说明表已成功同步至数据库。
Tips:每当需要修改blogpost应用的管理数据时,我们都可以先修改models,对blogpost调用makemigrations,让django迁移(修改)数据。
Django后台
创建超级用户
在进行模型注册前,我们需要先创建超级用户,以便我们能进入网站后台管理。
(env) $:python manage.py createsuperuser
Username (leave blank to use 'apple'): blog
Email address:
Password:
Password (again):
Superuser created successfully.
执行manage.py createsuperuser命令,username设置用户名为blog,email address可以为空,password设置为blogpost。
向管理站点注册模型
找到blogpost目录下的admin文件:
from django.contrib import admin
# 注册模型
from .models import Blog, Category, Tag
admin.site.register([Blog, Category, Tag])
网站后台
在浏览器输入http://127.0.0.1:8000/admin进入后台:
输入用户名,密码进入:
点击进入Blogs就可以添加我们的博客文章了:
在后台创建几篇文章,发现名称都一样,如下:
于是我们在models.py文件中添加如下语句:
class Category(models.Model):
"""
分类
"""
name = models.CharField(max_length=50)
# 添加语句
def __str__(self):
return self.name
class Blog(models.Model):
"""
博客
"""
title = models.CharField(max_length=50)
author = models.CharField(max_length=16)
content = models.TextField()
created = models.DateTimeField( auto_now_add=True)
category = models.ForeignKey(Category)
tags = models.ManyToManyField(Tag, blank=True)
# 添加语句
def __str__(self):
return self.title
Tag与Category相同。__str__
函数表示对象如何显示自己,一般系统默认使用<Blog: Blog object>
来表示对象, 通过这个函数可以告诉系统使用title或name字段来表示这个对象。
Django Shell
现在我们进入django shell进行数据库相关操作,执行manage.py shell
命令:
(env)$:python manage.py shell
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
获取数据(查)数据
all方法获取所有对象,get方法获取一个满足条件的对象。
>>> from blogpost.models import Blog
>>> Blog.objects.all()#查询所有数据对象
<QuerySet [<Blog: django教程>, <Blog: Django教程二>]>
>>> Blog.objects.get(id=1)#获取id=1的对象
<Blog: django教程>
>>> Blog.objects.get(title='Django教程二')#获取title='Django教程二'的对象
<Blog: Django教程二>
# 获取对象的属性信息
>>> b = Blog.objects.get(id=1)
>>> b.title
'django教程'
>>> b.content
'这是一篇django实战开放教程,开发系统为MacOS,开发环境为Python3.5+Django1.11。'
创建数据(增加)数据
两种创建数据的方法
>>> from blogpost.models import Blog, Category, Tag
>>> Category.objects.create(name='python test')
<Category: python test>
>>> t = Tag(name='learning django test')
>>> t.save()
>>>
查询一下看看:
>>> Category.objects.all()
<QuerySet [<Category: Django>, <Category: python test>]>
>>> Tag.objects.all()
<QuerySet [<Tag: learning django test>]>
修改数据
>>> Blog.objects.get(id=1)
<Blog: django教程>
>>> b.title
'django教程'
>>> b.title = 'django course'
>>> b.save()
>>> Blog.objects.all()
<QuerySet [<Blog: django course>, <Blog: Django教程二>]>
删除数据
直接调用delete方法删除对象
>>> b.delete()
(1, {'blogpost.Blog': 1, 'blogpost.Blog_tags': 0})
>>> Blog.objects.all()
<QuerySet [<Blog: Django教程二>]>
排序
执行order_by命令并以name属性排序,属性前面加一个负号表示逆序。
>>> Category.objects.order_by('name')#正序
<QuerySet [<Category: Django>, <Category: python test>]>
>>> Category.objects.order_by('-name')#逆序
<QuerySet [<Category: python test>, <Category: Django>]>
条件查询
filter方法可以查询不同条件的批量对象,详细的使用方法可以去看官方文档,中文推荐去看自强学堂的教程,也很不错。
>>> Category.objects.filter(name__contains='python')
<QuerySet [<Category: python test>, <Category: python test two>, <Category: python test thd>]>
name__contains
name后面有两个下划线,contains表示name中包含python关键字的对象。