文章目录
在Django中,不需要通过SQL语句直接跟数据库打交道,而是完全用Python的方式创建数据模型,之后交给Django完成数据库的操作。
1 新建表
无论当我们第一次在models.py中创建类对象还是对类中的属性进行修改,我们都会使用 python manage.py makemigrations 和 python manage.py migrate 两个命令。
当改动了model.py的内容之后执行命令:
python manger.py makemigrations
相当于在该app下建立migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py, 但是这个改动还没有作用到数据库文件。
然后执行:
python manager.py migrate
执行后将该改动作用到数据库文件。
1.1 修改models.py
首先在./blog/models.py中写一个类,这个类与数据库中的数据表具有对应关系。
代码如下:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class BlogArticles(models.Model):
title = models.CharField(max_length = 300) # ①
author = models.ForeignKey(User, related_name = "blog_posts") # ②
body = models.TextField()
publish = models.DateTimeField(default = timezone.now)
class Meta: # ③
ordering =("-publish", )
def __str__(self):
return self.title
说明:
这个类继承了django.db.models.Model类,在这个类中定义了一些属性,每个属性对应着将来数据库表中的一个字段。
语句①规定了字段title的属性为CharField()类型,并且以参数max_length = 300的形式说明字段的最大数量。
语句②通过字段author规定了博客文章和用户之间的关系:一个用户对应多篇文章,ForeignKey()就反映了这种“一对多”关系。类User就是BlogArticles的对应对象,related_name = "blog_posts"的作用是允许通过类User反向查询到BlogArticles。
语句③从名称上看貌似Python中的元类,但它跟元类不同。在此处,通过ordering =("-publish", )规定了BlogArticles实例对象的显示顺序,即按照publish字段值的倒序显示。
1.2 python manage.py makemigrations
执行:
~ cd DjangoDemo/mysite
~ python manage.py makemigrations
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model BlogArticles
从打印的信息可以看出,在 blog/migrations目录下创建了一个0001_initial.py文件,为BlogArticles的模型。
执行以下命令查看这个文件的作用:
~ python manage.py sqlmigrate blog 0001
BEGIN;
--
-- Create model BlogArticles
--
CREATE TABLE "blog_blogarticles" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(300) NOT NULL, "body" text NOT NULL, "publish" datetime NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id"));
CREATE INDEX "blog_blogarticles_author_id_ed798e23" ON "blog_blogarticles" ("author_id");
COMMIT;
通过打印信息可以清楚上述文件的功能是创建一个名称为blog_blogarticles的数据库表。再观察数据库表中的字段名称,除id是自动生成外,其他都是在数据模型类BlogArticles中所声明的字段及其属性。
1.3 python manage.py migrate
上面创建了一个能够建立数据库表的文件,下面就在此基础上,真正创建数据库了。
执行:
python manage.py migrate
打印信息如下:
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying blog.0001_initial... OK
Applying sessions.0001_initial... OK
1.4 命令作用域
另外一个需要注意的是这两个命令默认情况下是作用于全局,也就是对所有最新更改的models或者migrations下面的迁移文件进行对应的操作,如果要想仅仅对部分app进行作用的话,则执行如下命令:
python manage.py makemigrations ${appname}
python manage.py migrate ${appname}
如果要想精确到某一个迁移文件则可以使用:
python manage.py migrate ${appname} ${filename}
2 创建超管账号
这里讲最简单的额方式实现博客文章的发布,使用Django默认的管理功能就可以发布文章,但首先要创建超级管理员账号:
执行:
python manage.py createsuperuser
执行后
Username (leave blank to use 'tbc886'): admin
Email address: [email protected]
Password:
Password (again):
Superuser created successfully.
账号:admin
密码:2345.com
创建成功后,在浏览器地址栏输入:http://127.0.0.1:8000/admin/ 即可跳转到管理员界面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WgmbLrJo-1586310372641)(evernotecid://B1C45E84-DAD5-4A3E-8F09-F042CE8BEC59/appyinxiangcom/9699651/ENResource/p2448)]
3 发布博客文章
3.1 注册模块
打开./blog/admin.py文件,输入如下代码:
from django.contrib import admin
from .models import BlogArticles # ①
admin.site.register(BlogArticles) # ②
代码①将BlogArticles类引入当前环境,然后通过代码②将该类注册到admin中。
在调试模式下,如果没有新增文件,只是修改原有文件,则不需要重新启动Django,刷新浏览器页面即可。
刷新后即可看到新注册的blog模块。
添加一篇文章后,即可在数据库也查询到新增数据:
3.2 丰富页面功能
操作完上面步骤后,博客页面打开如下:
继续编辑./blog/admin.py文件:
from django.contrib import admin
from .models import BlogArticles
class BlogArticlesAdmin(admin.ModelAdmin):
list_display = ("title", "author", "publish")
list_filter = ("publish", "author")
search_fields = ("title", "body")
raw_id_fields = ("author",)
data_hierarchy = "publish"
ordering = ["publish", "author"]
admin.site.register(BlogArticles, BlogArticlesAdmin)
注:在./blog/models.py中使用了django.utils.timezone,为此需要安装一个pytz模块,用来提供时区数值。
刷新页面后:
4 总结
在Django中,开发者不需要直接通过SQL语句操作数据库,而是使用更Python化的方式实现对数据库的操作,这就是ORM(Object-Reelational Mapping
,对象关系映射)模式。
Django的ORM表现方式就是编写数据模型类,这些类通常写在每个应用的models.py文件中,当然也可以写在任何文件中。每个数据模型类都是django.db.models.Model的子类。应用的名称小写和数据模型类名称的小写共同组成一个数据库表的名称(${appname}_${modelname}),例如blog_blogarticels。
ORM模式的优点之一就是可移植性强,如果想改为MySQL数据库,只需要在seettings.py文件中做好新数据库的配置,然后进行迁移数据的操作即可完成数据库的移植,不需要对ORM进行任何修改。