django-Vue搭建博客:初始DRF

朱阳曜
2023-12-01

对于drf我们是陌生的,所以我们在使用DRF搭建前后端分离时需要提前学习DRF。

教程来源杜塞-django-vue系列
博客链接 传送门

DRF准备

首先进入虚拟环境,然后进入进入项目根目录,创建博客文章APP:

(venv) E:\drf>cd drf_vue_blog

(venv) E:\drf\drf_vue_blog>python manage.py startapp article

创建简单的博客文章模型:

# article/models.py

from django.db import models

# Create your models here.
from django.utils import timezone


# 博客文章
class Article(models.Model):
    # 标题
    title = models.CharField(max_length=100)
    # 正文
    body = models.TextField()
    # 创建时间
    created = models.DateTimeField(default=timezone.now)
    # 更新时间
    updated = models.DateTimeField(auto_now=True)


    def __str__(self):
        return self.title

前后端分离设计一个重要概念:序列化(后续讲解)。Django 有一个非常优秀的库 djangorestframework(后称 DRF)。它可以帮我们封装好序列化的底层实现,让开发者专注于业务本身。

安装DRF 及其他库依赖:

pip install djangorestframework
pip install markdown
pip install django-filter

然后将APP注册到列表:

# drf_vue_blo/settings.py
INSTALLED_APPS = [
    ···
	···
	···
    'article',
    'rest_framework'
]

最后进行数据迁移

(venv)E:\drf\drf_vue_blog>python manage.py makemigrations
(venv)E:\drf\drf_vue_blog>python manage.py migrate

序列化与Django

前后端分离的核心思想之一,就是两端互不交互不需要再插入模板语言,而只需要在约定好的接口传输数据。因此问题来了。

带Django程序运行过程中,变量都是存储在服务器内存中的;更重要的是,后端Django程序中存储的是python变量,而前端是Javascript变量,这两者无法进行交流
JSON 就是这种标准格式之一。它很轻量,表示出来就是个字符串,可以直接被几乎所有的语言读取,非常方便。

举个例子,把 Python 对象转换为 JSON ,这被称为序列化(serialization):

>>> import json
>>> person = dict(name='Trump', age=82)
>>> json.dumps(person)
# 这是个字符串
'{"age": 82, "name": "Trump"}'

把 JSON 转换为 Javascript 对象,被称为反序列化:

>>> json_str = '{"age": 82, "name": "Trump"}'
>>> json.loads(json_str)
# 这是个 js 对象
{'age': 82, 'name': 'Trump'}

总之,把变量从内存中变成可存储或传输的过程称之为序列化,反过来把变量内容从序列化的对象重新读到内存里称之为反序列化。

回顾 Django 传统流程对一个网络请求的处理:

def a_list(request):
    articles = Article.objects.all()
    return render(..., context={'articles': articles})

视图函数将数据作为上下文返回,通过模板引擎将上下文渲染为页面中的数据。

Restful 的处理流程仅增加了一步,即对数据序列化的处理:

def a_list(request):
    articles = Article.objects.all()
    # 序列化数据
    serializer = Serializer(articles, many=True)
    return JsonResponse(serializer.data, safe=False)

数据被序列化后为Json字符串,直接交付前端处理。
这就是前后端分离的雏形。

  • 后端注重提供数据:
  • 前端注重于数据操作、渲染页面。

这里又出现了与前后端分离联系很紧密的新概念:Rest(表现层状态转化) 和 Restful。Restful 架构是指客户端和服务器之间的交互、操作符合 Rest 规范,即:每一个URI代表一种资源;客户端和服务器之间,传递资源的表现层;客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。有点难理解,推荐读物阮一峰的博客和知乎文章。

hello world

按照这个思路,我们来写一个文章列表接口。

article 模型在前面已经写好了,接下来写视图:

# article/views.py
from django.shortcuts import render

# Create your views here.
from django.http import JsonResponse
from article.models import Article
from article.serializers import ArticleListSerializer

def article_list(request):
    articles = Article.objects.all()
    serializers = ArticleListSerializer(articles, many=True)
    return JsonResponse(serializers.data, safe=False)

代码一共3行:

  • 取出所有文章的 QuerySet;
  • 根据 QuerySet 数据,创建一个序列化器;
  • 将序列化后的数据以 Json 的格式返回。

与前文提到的一直,不再使用模板,而是 Json 数据。

代码中的 ArticleListSerializer我们还没写,其实他就是我们定义的序列化器。
新建py文件名为:article/serializers.py,写入以下代码:

# article/serializers.py
from rest_framework import serializers

class ArticleListSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)

    title = serializers.CharField(allow_blank=True, max_length=100)

    body = serializers.CharField(allow_blank=True)

    created = serializers.DateTimeField()

    updated = serializers.DateTimeField()

序列化类看上去很想From类,它指定接口数据和各个字段的类型,自动对请求和响应中的数据进行序列化和反序列化的转换。DRF 是已经定义好的,我们无需关心底层逻辑。

最后将各级 urls.py配置好:

# drf_vue_blog/urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/article/', include('article.urls', namespace='article')),
]

以及:

# article/urls.py
from django.urls import path, include
from article import views
urlpatterns = [
   path('', views.article_list, name='list'),
]

代码部分已完成。

接下来创建管理员用户,并在后台添加几条article数据数据用来测试,启动服务器,可以看到如下Json数据(稍作排版,当然也可以使用浏览器插件自动排版):

[
	{
	"id": 1, 
	"title": "python", 
	"body": "Python is one of my favorite programming languages", 
	"created": "2021-06-11T11:35:50Z", 
	"updated": "2021-06-11T11:37:14.001883Z"
	}, 
	{
	"id": 2,
	"title": "Java",
	"body": "I like too\u3002", 
	"created": "2021-06-11T11:37:15Z", 
	"updated": "2021-06-11T11:37:31.117904Z"
	}, 
	{"id": 3, 
	"title": "test", 
	"body": "I'm testing", 
	"created": "2021-06-11T11:37:34Z", 
	"updated": "2021-06-11T11:37:56.285260Z"
	}
]

虽然简陋,但也是你已经完成了一个简单的接口:

创建管理员用户和添加数据是很基础的内容,这里不再赘述。

排错

若出现以下错误,需要在article/urls.py内定义app_name

django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.

若出现警告以下警告,点击这里

WARNINGS:
article.Article: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
        HINT: Configure the DEFAULT_AUTO_FIELD setting or the ArticleConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.

总结

  • 转变静态模式思维
  • 自行排错
 类似资料: