Django 作为 Python 社区最受欢迎的 Web 框架之一,凭借其高度抽象的组件和强大方便的脚手架,将快速且流畅的开发体验演绎到了极致。而 Nuxt 作为从 Vue.js 进化而来的前端框架,能够轻松胜任复杂的 SPA(单页应用)开发。两者相遇,能够擦出怎样的火花?这篇教程将用 Django + Nuxt 实现带有完整的增删改查(CRUD)功能的全栈应用。最后郑重警告:不要在深夜阅读此教程!!!

本文所涉及的源代码都放在了 Github 上,如果您觉得我们写得还不错,希望您能给❤️这篇文章点赞+Github仓库加星❤️哦~ 本文代码改编自 Scotch

项目初始化

在这一系列教程中,我们将会实现一个全栈美食分享网站,后端用 Django 实现,前端则是 Nuxt 框架,下面是最终完成后的项目效果:

预备知识

本教程假定你已经知道了

  • 基本的 Python 3 语言知识,包括使用 pip 安装包
  • Django 框架的基础概念(MTV 架构),可参考这篇教程进行学习
  • Vue 的基础概念,以及用 npm 工具链的使用,可参考这篇教程
  • 前后端分离的基本概念,包括前端如何通过发起 HTTP(S) 请求从后端获取数据

学习目标

学完这篇教程后,你将:

  • 了解用 pipenv 工具管理 Python 依赖
  • 学会用 Django REST Framework 快速开发 REST API
  • 学会用 Nuxt 框架快速开发 SPA(单页应用),能够从后端获取数据并渲染

用 pipenv 初始化 Python 环境

首先创建项目目录,并进入:

$ mkdir recipes_app && cd recipes_app

在这个项目中,我们用 pipenv 来管理 Python 项目的环境依赖。Pipenv 是 Python 社区偶像级大师 Kenneth Reitz 牵头开发的开发流程优化工具,立志集所有项目管理工具(Node 的 npm、Ruby 的 bundler、PHP 的 composer 等等)的优势为一体。我们通过下面的命令安装 pipenv,并创建项目的依赖环境:

$ pip install pipenv
$ pipenv shell

如果看到命令提示符前面出现 (recipes_app-nV3wuGJ1) 的提示(后面那串随机字符串可能不一样),就表明我们已经成功地创建了项目独有的虚拟环境!我们接着安装 Django “三件套”:

  • Django: Django 框架本身,提供了丰富且强大的服务器开发组件;
  • DRF (Django Rest Framework):Django 框架的超级搭档,大大方便了 REST API 的开发;
  • Django CORS Headers:用于实现跨域资源请求(CORS)的 Django 中间件(如果你不了解 CORS,可以参考阮一峰的日志)。

安装命令如下:

(recipes_app-nV3wuGJ1) $ pipenv install django django-rest-framework django-cors-headers

这时 pipenv 便产生了 Pipfile 文件,它的作用就类似 Node 项目中的 package.json 文件:

[[source]]
url = "https://mirrors.aliyun.com/pypi/simple/"
verify_ssl = true
name = "pypi"[packages]
django = "*"
django-rest-framework = "*"
django-cors-headers = "*"[dev-packages][requires]
python_version = "3.6"

然后用 Django 脚手架创建服务器项目 api 的基本结构,并进入到 api创建一个子应用 core

(recipes_app-nV3wuGJ1) $ django-admin startproject api
(recipes_app-nV3wuGJ1) $ cd api
(recipes_app-nV3wuGJ1) $ python manage.py startapp core

接着进行数据库迁移,并创建用于登录后台管理的超级用户:

(recipes_app-nV3wuGJ1) $ python manage.py migrate
(recipes_app-nV3wuGJ1) $ python manage.py createsuperuser

按照问题输入信息即可。要记住用户名和密码哦!然后运行开发服务器:

(recipes_app-nV3wuGJ1) $ python manage.py runserver

访问 http://localhost:8000/admin,可以看到后台管理的登录页面。输入刚才创建的超级用户的用户名和密码,就进入了后台管理系统,如下所示:

熟悉的界面,但是——没什么东西,而且全是英文!别担心,后面我们会一个个搞定。

用 Django 实现 REST API

接下来我们将实现本项目所需要用的所有 API。对,你没有听错,我们会在这一步实现所有后端接口,大概只 10 分钟左右可以敲完!这就是 Django 的宣言:

The web framework for perfectionists with deadlines.

“为赶时间的完美主义者而生!”

全局配置

首先,在全局配置文件 settings.py 中做如下改动:

  1. INSTALLED_APPS 中添加 rest_frameworkcorsheaderscore,前两个分别是 Django Rest Framework 和 Django CORS Headers 的应用,最后一个是我们网站的应用;
  2. MIDDLEWARE 中添加 corsheaders.middleware.CorsMiddleware,注册跨域请求中间件(注意一定要放在最前面!);
  3. 设置 CORS_ORIGIN_WHITELIST,添加跨域请求白名单,这里我们先写上 http://localhost:3000,后面开发前端时将用到;
  4. 设置 LANGUAGE_CODEzh-hans,可以将后台管理设置为中文,非常方便;
  5. 设置 MEDIA_URLMEDIA_ROOT,用于在开发中提供图片资源文件的访问。

具体代码如下:

# ...INSTALLED_APPS = [# 默认的 App ...'rest_framework','corsheaders','core',
]MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware',# 默认的中间件 ...
]CORS_ORIGIN_WHITELIST = ('http://localhost:3000',
)# ...LANGUAGE_CODE = 'zh-hans'MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

实现 core 应用

接下来就是实现 core 这个 Django 应用。实现一个 Django 应用大致都是按照这样的流程:

  1. 定义数据模型(models.py),用于实现和数据库之间的绑定;
  2. 定义后台管理配置(admin.py),用于在后台管理系统中进行操作;
  3. 定义序列化器(serializers.py),仅当实现 REST API 时需要,用于提供数据模型的 JSON 序列化(或其他数据交换格式);
  4. 定义视图(views.py),用于实现具体的业务逻辑;
  5. 定义路由(urls.py),用于定义路由规则,将其映射到相应的视图;
  6. 将应用路由接入全局路由文件(api/urls.py)中。

我们从第一步开始,完成菜谱 Recipe 数据模型如下:

from django.db import modelsclass Recipe(models.Model):DIFFICULTY_LEVELS = (('Easy', '容易'),('Medium', '中等'),('Hard', '困难'),)name = models.CharField(max_length=120, verbose_name='名称')ingredients = models.CharField(max_length=400, verbose_name='食材')picture = models.FileField(verbose_name='图片')difficulty = models.CharField(choices=DIFFICULTY_LEVELS, max_length=10,verbose_name='制作难度')prep_time = models.PositiveIntegerField(verbose_name='准备时间')prep_guide = models.TextField(verbose_name='制作指南')class Meta:verbose_name = '食谱'verbose_name_plural = '食谱'def __str__(self):return '{} 的食谱'.format(self.name)

其中,class Meta 定义了 Recipe 的元数据;__str__ 方法定义了一个菜谱对象转换为字符串时应该怎样显示。这些设置的作用在打开后台管理系统之后就会很清晰了。想要了解更多关于 Django 数据模型的知识,请参考相关中文文档。

第二步,为 core 子应用配置相应的后台管理功能。非常简单,只需注册定义好的 Recipe 模型:

from django.contrib import admin
from .models import Recipe# Register your models here.
admin.site.register(Recipe)

第三步,定义序列化器 serializers.py(脚手架并不会自动创建,需要手动创建)。序列化器是 Django Rest Framework 提供的功能,能够非常方便地将 Django 数据模型序列化成相应的 JSON 数据格式。在这里,我们定义一个 RecipeSerializer,并在 class Meta 中指定对应的数据模型为刚才创建的 Recipe,并选择相应的字段展示:

from rest_framework import serializers
from .models import Recipeclass RecipeSerializer(serializers.ModelSerializer):class Meta:model = Recipefields = ('id', 'name', 'ingredients', 'picture','difficulty', 'prep_time', 'prep_guide')

第四步,实现视图。这里我们采用开挂模式,直接调用 Django Rest Framework 提供的模型视图集(ModelViewset)直接搞定数据模型的增删改查逻辑:

from rest_framework import viewsets
from .serializers import RecipeSerializer
from .models import Recipeclass RecipeViewSet(viewsets.ModelViewSet):serializer_class = RecipeSerializerqueryset = Recipe.objects.all()

只需指定 serializer_class(序列器类)和 queryset(模型查询集),就自动定义好了模型的添加、删除、查询和修改!虽然视图集非常强大,但是如果要实现更加灵活的业务逻辑,那么还是要为每个接口定义单独的视图类才行。

第五步,实现路由。由于我们上一步使用了视图集,因此只需先调用 DefaultRouter 自动生成相关的路由,然后加入记录路由映射的列表 urlpatterns 中:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import RecipeViewSetrouter = DefaultRouter()
router.register(r'recipes', RecipeViewSet)urlpatterns = [path('', include(router.urls)),
]

router 为我们自动生成以下路由:

  • /recipes/:创建食谱(POST 方法)或读取食谱列表(GET方法);
  • /recipes/{id}:获取单个食谱(GET)、更新单个食谱(PUT)或删除食谱(DELETE)。

注意

在 Django 路由定义中不包括 HTTP 方法,具体的 HTTP 方法可以在视图中读取并判断。

最后一步,我们将 core 子应用中的路由接入全局路由:

from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('api/', include('core.urls')),
]

没错,关于食谱的增删改查的 API 我们全都实现了!不信?先运行开发服务器:

(recipes_app-nV3wuGJ1) $ python manage.py runserver

由于 Django REST Framework 为我们提供了测试 API 的 Web 界面,因此这里就不用 Postman 等工具进行测试了。用浏览器访问 localhost:8000/api/recipes,就进入了如下所示的 API 测试页面:

这个页面的下方还有添加数据(发起 POST 请求)的表单,我们填一些数据,然后点击 POST 按钮:

然后再次访问食谱列表页面,就有我们刚刚添加的食谱了!此外,你还可以尝试访问单个食谱的详情页面(例如 localhost:8000/api/recipes/1),并且可以通过 Web 页面直接修改或删除哦!

用 Nuxt.js 实现网站首页

Django 的 MTV 架构固然优秀,但是随着现在的业务逻辑越来越多地向前端倾斜(也就是现在流行的富前端应用),其中的 T(Template)需要更强大的武器来解决,这里就是我们的第二位主角 Nuxt。

用脚手架初始化 Nuxt 项目

我们将把所有的前端代码放到 client 目录中,不过无需自己创建,我们调用 nuxt 的脚手架来创建前端应用:

$ npx create-nuxt-app client

之后脚手架应用会询问一系列问题,按下面的截图进行选择(当然作者名填自己):

我们对 Nuxt 脚手架生成的目录结构稍作讲解。可以看到 client 目录下有以下子目录:

  • assets:存放图片、CSS、JS 等原始资源文件
  • components:存放 Vue 组件
  • layouts:存放应用布局文件,布局可在多个页面中使用
  • middleware:存放应用的中间件。Nuxt 中的中间件指页面渲染前执行的自定义函数(本教程中不需要)
  • pages:应用的视图和路由。Nuxt 会根据此目录中的 .vue 文件自动创建应用的路由
  • plugins: 存放 JavaScript 插件,用于在应用启动前加载(本教程中不需要)
  • static:存放通常不会改变的静态文件,并且将直接映射到路由(即可通过 /static/picture.png 访问)
  • store:存放 Vuex Store 文件(本教程中不需要)

本项目所用到的图片资源请访问我们的 GitHub 仓库,并下载到对应的目录中。

编写前端首页

我们在 client/pages 中创建 index.vue 文件,并在其中实现我们的前端首页:

<template><header><div class="text-box"><h1>吃货天堂 												

全栈“食”代:用 Django + Nuxt 实现美食分享网站(上)相关推荐

  1. 全栈“食”代:用 Django + Nuxt 实现美食分享网站(一)

    Django 作为 Python 社区最受欢迎的 Web 框架之一,凭借其高度抽象的组件和强大方便的脚手架,将快速且流畅的开发体验演绎到了极致.而 Nuxt 作为从 Vue.js 进化而来的前端框架, ...

  2. 塔望3W消费战略全案|小靳师傅:地方美食如何乘上新速食时代快车

    小靳师傅品牌全案服务 公司:上海中达食品有限公司 品牌:小靳师傅 行业:即食.自热.食品行业 服务:品牌全案服务 [项目背景] 中华的美食有着悠久的历史,与中国的文化息息相关.在历史的发展长河与生产生 ...

  3. python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)

    一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post ...

  4. python 全栈开发,Day79(Django的用户认证组件,分页器)

    一.Django的用户认证组件 用户认证 auth模块 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中: 如果用户存在于数据库中,然后再验证用户 ...

  5. Python全栈(十)Django框架之6.ORM模型基本使用

    文章目录 一.ORM创建模型和映射数据库 1.创建模型 2.数据库映射 二.ORM模型数据操作 1.添加数据 2.查询数据 3.删除数据 4.更新数据 三.ORM实现图书管理系统 一.ORM创建模型和 ...

  6. Python全栈工程师学习笔记 | Django的模型层

    Model模型 模型是你的数据的唯一的.权威的信息源.它包含你所储存数据的必要字段和行为. 通常,每个模型对应数据库中唯一的一张表. 每个模型都是django.db.models.Model的一个Py ...

  7. python datetime需要安装_Python全栈工程师学习笔记 | Django的模型层

    Model模型 模型是你的数据的唯一的.权威的信息源.它包含你所储存数据的必要字段和行为. 通常,每个模型对应数据库中唯一的一张表. 每个模型都是django.db.models.Model的一个Py ...

  8. Python全栈(十)Django框架之9.聚合函数和表达式

    文章目录 一.聚合函数 1.Avg函数 2.聚合函数实现链式调用 3.aggregate和annotate的区别 4.Count函数 5.Max和Min函数 6.Sum函数 二.F表达式和Q表达式 1 ...

  9. Python全栈(十)Django框架之10.ORM模型对象和QuerySet方法

    文章目录 一.objects对象源码解读 二.QuerySet方法 1.exclude方法 2.order_by方法 3.values方法 4.values_list方法 5.create方法 6.g ...

最新文章

  1. Form表单提交前进行JS验证的3种方式
  2. C 函数 toascii
  3. Singing Everywhere
  4. php生成 sku_高并发下,php与redis实现的抢购、秒杀功能
  5. 跨平台加密版 SQLite 3 - wxSQLite3
  6. android 系统(162)---O版本的Camera Startup time比N版本时间长
  7. camera(22)---camera 客观测试 Imatest教程--色彩还原度测试
  8. 产品研发过程管理专题——软件测试过程管理实践
  9. SpringBoot--自动装配之Import注解以及源码分析
  10. Cobalt Strike神器使用教程
  11. 360安全卫士 免杀
  12. 使用python处理wps表格_Python处理Word文件的实用姿势
  13. wireshark密码嗅探侵入后台管理系统
  14. “函数...已有主体”问题解决
  15. 用计算机完成下表的视距测量计算公式,中南大学工程测量计算题库及参考答案...
  16. 手绘风格的白板Excalidraw
  17. 618年中大促 ,全场6折起!限量周边8件套!
  18. 国产ETL etl-engine 星光不问赶路人 时我不待
  19. 网站统计IP PV UV实现原理
  20. windows 命令行切换目录

热门文章

  1. substr函数的用法
  2. 加载任务地图信息失败!!!
  3. 实现页面滚动背景图片不动的效果
  4. 鸿蒙 林蒙什么关系,斗鱼林蒙叫什么 拖米林蒙双排怎么回事
  5. MOLAP和ROLAP
  6. 腾讯短信发送(基于v3版本封装)
  7. 3天线下K8s封闭式实战培训
  8. 对话 Jessica Hamrick:和 Django 的情缘是我前行的动力
  9. WireShark提取天猫魔盒请求链接
  10. autotype安全 fastjson_fastjson1.2.61发布,增加 autoType 安全黑名单