1.1安装Django
1.2创建第一个项目
django-admin startproject mysite
1.2.1运行开发服务器
python manage.py runserver
November 05, 2021 - 06:55:35
Django version 2.0.5, using settings ‘mysite.settings’
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
1.2.2 项目设置
打开settings.py文件查看当前项目的配置内容
1.2.3 项目和应用程序
在Django中被视为基础某些设置项的Django的安装结果;
应用程序被成为视图(views),模型(model),模板(migration)以及URL的组合
1.2.4 创建应用程序
python manage.py stratapp blog
1.3设计博客数据方案
模型表述为一个Python类,并第一位Django.db.models.Models的子类。
其中,每个属性视为一个数据库字段。Django针对定义与models.py 文件中的每个模型创建一个表。当创建一个模型时,Django提供了一个实用的API,从而看方便的查看数据库中的对象。
定义一个Post模型,并向博客应用程序的models.py中添加下面的代码行
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
# Create your models here.
class Post(models.Model):
STATUS_CHOICE = (
('draft', 'Draft'),
('publish', 'Publish'),
)
title = models.CharField("标题", max_length=250) # 帖子的标题字段,在SQL数据库中会被转换成为VARCHAR列
slug = models.SlugField(max_length=250,
unique_for_date='publish') # 用于URL中,作为剪短的标记,因包含字母、数字、下划线以及连字符。
author = models.ForeignKey( User,
on_delete=models.CASCADE,
related_name='blog_posts') # 字段表述为一个外键,并定义多对一的关系
body = models.TextField("正文") # 帖子的正文部分,会转换正SQL中的TEXT列
publish = models.DateTimeField("上传时间", default=timezone.now) # 帖子的发布时间
create = models.DateTimeField("创建时间", auto_now_add=True) # 帖子的创建时间
update = models.DateTimeField("修改时间", auto_now=True) # 帖子的修改时间
status = models.CharField(max_length=10,
choices=STATUS_CHOICE,
default='draft') # 帖子的状态
class Meta: # 包含了元数据。默认状态下,查新元数据是,将通知DJango对publis字段的结果以降序排序。通过前面的符号前缀排列
ordering = ('-publish',)
def __str__(self):
return self.title
1.3.1 激活应用程序
编辑settings.py文件,并向INSTALLEN_APPS设置中添加blog.apps.BlogConfig
1.3.2 设置并使用迁移方案
- 前述内容针对博客帖子创建了数据模型,我们需要对此定义数据库表。
- Django配置了迁移系统,跟中模型产生的变化内容,并将其传送至数据库中。相应的, migrate命令可针对INSTALLEN_APPS列出的全部应用程序进行迁移操作并同步对应的数据库
- 首先需要针对Post模型创建初始转移。
python manage.py makemigrations blog
结果如下
Django在blog应用程序的migrations目录内进生成了0001_initial.py文件,我们可以打开文件查看迁移结果。
- 创建模型表。sqlmigrate命令将使用到迁移名称并在不执行SQl的情况下返回其SQL。
运行下面的命令并检查第一次迁移的SQL输出结果
python managy.py sqlmigrate blog 0001
返回结果如下
BEGIN;
–
– Create model Post
–
CREATE TABLE “blog_post” (“id” integer NOT NULL PRIMARY KEY AUTOINCREMENT, “title” varchar(250) NOT NULL, “slug” varchar(250) NOT NULL, “body” text NOT NULL, “publish” datetime NOT NULL, “create” datetime NOT NULL, “update” datetime NOT NULL, “status” varchar(10) NOT NULL, “author_id” integer NOT NULL REFERENCES “auth_user” (“id”) DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX “blog_post_slug_b95473f2” ON “blog_post” (“slug”);
CREATE INDEX “blog_post_author_id_dd7a8485” ON “blog_post” (“author_id”);
COMMIT;
不难看出上面执行的就是一段MYSQL字段
家下来将数据库与新模型进行同步。运行一下命令来应用现有转移
python manage.py migrate
显示如下结果
1.4 针对模型创建管理站点
之前定义的Post模型,本节将创建简单的管理站点并对博客帖子进行适当管理。
1.4.1创建超级用户
首先要创建一个用户并管理站点。运行以下命令
python manage.py createsuperuser
输入用户名,邮箱,密码即可
1.4.2Django管理站点
启动服务其后,在浏览器输入http://127.0.0.1:8000/admin回车后进入登录页面
1.4.3向管理站点中添加模型
编辑blog应用程序中的admin.p文件
from django.contrib import admin
from.models import Post
# Register your models here.
admin.site.register(Post)
然后在刷新管理站点页面
进入Post,点击哟偶上交的add链接,即可添加新的帖子
输入成功后点击Save就可以进行博客的添加了
1.4.4定制模型显示方式
编辑blog应用程序中的admin.py文件
from django.contrib import admin
from .models import Post
# Register your models here.
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'author', 'publish',
'status')
list_filter = ('status', 'create', 'publish', 'author')
search_fields = ('title', 'body')
prepopulated_fields = {'slug': ('title',)}
raw_id_fields = ('author',)
date_hierarchy = 'publish'
ordering = ('status', 'publish')
1.5与QuerySet和管理器协同工作
本节将讨论如何从数据库中获取信息并与其进行交互。
Django设置了强大的数据库抽象API,并将此方便的创建获取,更新以及删除对象。同时DJango中对象关系映射器兼容于PostgreSQL、SQLite、以及Oracle。需要注意的是,我们可以在项目中的settings.py文件中的DATABASES设置项中定义当前的项目的数据库。DJango可以一次于多数据库协同工作,用户可以对数据库路由其进行编程,以创建自己的路由方案。
1.5.1创建对象
打开终端,运行下面命令启动python shell
python managy.py shell
>>> from django.contrib.auth.models import User
>>> from blog.models import Post
>>>> user = User.objects.get(username='jiuer')
>>> post = Post(title='Another post',
... slug='second_blog',
... body='Hello Blog',
... author=user)
>>> post.save()
这样就可以通过shell创建一个博客了
1.5.2更新对象
我们可以修改博客的标题等等
>>> post.title = 'New title'
>>> post.save()
1.5.3 获取对象
DJango队形关系映射机制基于QuerySet
获取所有对象
>>> all_post = Post.objects.all()
>>> all_post
<QuerySet [<Post: New title>, <Post: Django创建博客>]>
- 使用filter()方法过滤
>>> Post.objects.filter(author__username='jiuer')
<QuerySet [<Post: New title>, <Post: Django创建博客>]>
>>> Post.objects.filter(author__username='jiuer').filter(title='New title')
<QuerySet [<Post: New title>]>
- 使用exclude()方法排除只等的结果
>>> Post.objects.exclude(title='New title')
<QuerySet [<Post: Django创建博客>]>
- 使用order_by()排序方法(默认是升序)
>>> Post.objects.order_by('title')
<QuerySet [<Post: Django创建博客>, <Post: New title>]>
>>> Post.objects.order_by('-title')
<QuerySet [<Post: New title>, <Post: Django创建博客>]>
1.5.4 删除对象
>>> post = Post.objects.get(id = 2)
>>> post
<Post: New title>
>>> post.delete()
(1, {'blog.Post': 1})
1.5.5评估QuerySet
我们可以链接任意多个过滤器到一个QuerySet上,在QuerySet计算执勤并不会访问数据库。QuerySet仅在以下场合被计算
- 首次迭代时
- 当对QuerySet访问时
- 当对QuerySet缓存时
- 当对QuerySet上调用repr()或者len()时
- 当在QuerySet上显式调用list()时
- 当在某个语句中对QuerySet进行测试时,如bool()、or、and或者if
1.5.6 创建模型管理器
可以针对模型定义定制管理器。下面将创建定制管理器并检索包含published状态的全部帖子。
对此,存在两种方式可向模型中添加管理器,即添加额外的管理器方法,或者修改初始管理器QuerySet。其中第一个方法提供了相应的QuerySet API,如Post,object.may_manager():而地二哥方法则提供了Post.my_manager.all()。该管理器可通过Post。published.all()检索帖子
编辑models.py 文件,并添加定制管理器
# Create your models here.
class PublishManager(models.Manager):
def get_queryset(self):
return super(PublishManager,
self).get_queryset().filter(status='publish')
class Post(models.Model):
……
objects = models.Manager()
published = PublishManager()
管理器的get_queryset()方法返回将可执行的QuerySet。我们将复写giant方法,以在最终的QuerySet中包含自定义过滤器,之前曾定义了定制管理器,并将其添加至Post模型中,此处可对其加以使用并执行查询。
这样就可以根据部分字段来进行查询
1.6 构建列表和详细视图
在了解了如何使用ORM后,即可着手准备构建博客应用程序的视图。Django视图仅表示为一个Python函数,接收web请求并返回一个web相应。另外,返回相应结果的全部逻辑均位于视图中。
首先要创建应用程序视图,并于随后针对每个视图定义URL。最后还需要创建HTML末班,以渲染视图所身材更的数据。
1.6.1生成列表和视图
线面创建视图以显示帖子列表。编辑blog应用程序的views.py文件。
from django.shortcuts import render
from .models import Post
# Create your views here.
def post_list(request):
posts = Post.publish.all()
return render(request,'blog/post/list.html',{'posts':posts})
def post_detail(request,year,month,day,post)
post = get_object_or_404(Post,slug=post,status='published',
publish_year=year,
publish_month = month,
publish__day=day)
return render(request,'blog/post/detail.html',{'post':post})
1.6.2箱视图添加URL路径
URL路径可将URL映射至视图上
编辑blog中的url.py(不存在urls.py文件的话,自行创建一个)
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('',views.post_list,name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>',views.post_detail,name='post_detail'),
]
1.6.3模型的标准URL
可以使用上节定义的post_detail URL针对Post对象构建标准URL
修改models.py文件
from django.urls import reverse
class Post(models.Model):
……
def get_absolute_url(self):
return reverse('blog:post_datil',args=[self.publish.year,self.publish.month,self.publish.day,self.slug])
1.7 创建视图模板
创建目录
编辑base.html
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<link href="{% static 'css/blog.css' %}" rel="stylesheet">
</head>
<body>
<div id = "content">
{% block content %}
{% endblock %}
</div>
<div id="sidebar">
<h2>My blog</h2>
<p>This is my Blog.</p>
</div>
</body>
</html>
编辑post/list.html
{% extends "blog/base.html" %}
{% block title %} My Blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">Published {{ post.publish }} by {{ post.author }} </p>
{{post.body|truncatewords:30|linebreaks}}
{% endfor %}
{% endblock %}
编辑post/detail.html
{% extends "blog/base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<h1>{{ post.title }}</h1>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|linebreaks }}
{% endblock %}