设计数据库和表结构是做网站的基础;在Django中,不需要通过SQL直接跟数据交互,而是完全用Python的方式创建数据模型,之后交给Django完成数据库操作;
./blog/models.py
中写一个类BlogArticles
;BlogArticles类:
django.db.models.Model
;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") # 外键来自User,表示用户、文章 一对多的关系;related_name="blog_posts"作用是允许通过User类反向查找到BlogArticles;
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
class Meta: # 与元类不同
ordering = ("-publish",) # 规定BlogArticles实例对象按publish字段值倒序显示;
def __str__(self):
return self.title
mysite1
目录下的settings.py
中注册blog
应用;python manage.py makemigrations
(记得先执行下ls
);创建存储应用的数据库表结构的指令的文件;这里报了一个错误:
TypeError: __init__() missing 1 required positional argument: 'on_delete'
原因:
django 升级到2.0之后,表与表之间关联的时候,必须要写on_delete参数;
on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE, # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError
# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET, # 删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
这里我们使用关联删除:on_delete=models.CASCADE
;
修改代码如下:
author = models.ForeignKey(
User, related_name="blog_posts", on_delete=models.CASCADE
)
重新执行上述命令:
$ ls
blog db.sqlite3 manage.py mysite1
$ python manage.py makemigrations
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model BlogArticles
现在,在blog/migrations
目录下我们通过执行makemigrations
命令自动创建了一个BlogArticles
模型:0001_initial.py
# Generated by Django 3.0.8 on 2020-07-07 11:06
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='BlogArticles',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=300)),
('body', models.TextField()),
('publish', models.DateTimeField(default=django.utils.timezone.now)),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='blog_posts', to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ('-publish',),
},
),
]
这段代码的含义可以使用命令python manage.py sqlmigrate blog 0001
查看:
blog_blogarticles
的数据库表,blog是应用名,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") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "blog_blogarticles_author_id_ed798e23" ON "blog_blogarticles" ("author_id");
COMMIT;
python manage.py migrate
创建数据库;$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying blog.0001_initial... OK
现在,使用Navicat Premium打开根目录下的数据库文件,查看相应的数据库表结构,就可以看见已经创建好的表blog_blogarticles:
最简单的发布——使用Django默认的管理功能发布文章;要使用此方法需要先创建超级管理员(创建后牢记用户名和密码);
python manage.py createsuperuser
;$ python manage.py createsuperuser
Username (leave blank to use 'huaqiang'): baby_hua
Email address: [email protected]
Password: h1-8
Password (again):
Superuser created successfully.
这里:
还记得blog/admin.py文件的作用吗:
编辑blog/admin.py:
from django.contrib import admin
# Register your models here.
from .models import BlogArticles # 引入BlogArticles类
admin.site.register(BlogArticles) # 在admin中注册该类
我们看到了一个新注册的BLOG:
提供时区数值:blog/models.py中使用的django.utils.timezone
,依赖模块pytz
pytz
模块,执行命令pip install pytz
;重启项目;查看已经创建的文章列表:列项的显示还可以更丰富一些,只需编辑blog/admin.py
from django.contrib import admin
# Register your models here.
from .models import BlogArticles # 引入BlogArticles类
class BlogArticlesAdmin(admin.ModelAdmin):
list_display = ("title", "author", "publish")
list_filter = ("publish", "author")
search_fields = ("title", "body")
raw_id_fields = ("author",)
date_hierarchy = "publish"
ordering = ["publish", "author"]
admin.site.register(BlogArticles, BlogArticlesAdmin) # 在admin中注册该类