Django 学习记录 —— 接口设计初体验

本文基于以下环境展开:
Django: v3.0.4(djangorestframework v3.11.0)
Python: v3.7.4

前期准备

在展开正文内容之前,除了要准备基础的环境(python、django以及数据库)之外,还有项目框架的构建,这部分主要简要的写一下这点。

创建工程

django 命令: django-admin startproject project_name [directory]

django-admin startproject mysite
# or
django-admin startproject mysite .  # 当前目录

生成的目录结构如下:
django-admin startproject mysite

创建应用

工程复杂度比较高的时候,可以构建多个 app 的形式,也方便以后复用

django 命令:
python manage.py startapp app_name or django-admin startapp app_name

python manage.py startapp news 
# or
django-admin startapp news 

以上两种方式生成的目录结构如下:
创建应用

四大步实现接口

Django 有很成熟的写 Web APIs 框架 —— Django REST framework(DRF),官方总结了很多 DRF 的优点,就不再赘述,这里主要从自身使用角度来讲:

  • 对新手来说,DRF 非常友好,model -> serializer -> view -> url 一条线的实现路径,只需要了解一些基础知识就可以实现 restful api;

  • 对有基础的同学来说,DRF 认证、权限等都支持多种方式,可选择性大,可扩展性强,可以满足多种需求。

step1: model

根据数据库存储字段需求来设计
官方举例的模型很具代表性,在此借用官方例子

构建模型

# mysite/news/models.py
from django.db import models

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)
    # 模型显示,默认为 id
    # eg. <QuerySet [<Reporter: Smith>, <Reporter: Lily>]>
    def __str__(self):
        return self.full_name
    # 可对要存储到数据库的数据进行处理    
    def save(self, *args, **kwargs):
        super(Reporter, self).save(*args, **kwargs)
    # 序列中增加一个字段,但不会写入数据库    
    @property
    def keyword(self):
        return self.full_name

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
   
    def __str__(self):
        return self.headline

字段 : CharField、TextField 为数据库表字段类型,ForeignKey外键使不同表之产生关联
字段选项 : max_length(字符串长度)是 CharField 必选项 ;
注:

  • primary_key 未指定字段时,会自动生成一个整型自动递增的字段 id;
  • 一个model(一张表)只能指定一个字段为 primary_key。

新建表

前提:

  1. 将 app 加入到配置文件的 INSTALLED_APPS;
  2. 配置目标数据库信息;
# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',			   # 使用 DRF,需要加上此项
    'news',                        # 新创建应用
]
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',    # 数据库类型
        'NAME': 'mysite',                        # 数据库名称
        'USER': 'root',                          # 数据库用户
        'PASSWORD': '123456',                    # 数据库密码
        'HOST': 'localhost',                     # 数据库所在主机
        'PORT': '3306'                           # 主机端口
    }
}

配置完成后,执行以下两步实现数据库迁移和表生成:

# 在项目路径下执行
python manage.py makemigrations news
python manage.py migrate news

注:若DATABASES配置了多个数据库, 执行 migrate 过程中要使用 --database参数指明

数据库新生成的表如下(数据库中表名生成格式:appName_modelName)

数据库信息

step2: serializer

与 model.py 字段对应,进行序列化

from rest_framework import serializers
from news.models import Reporter, Article

class ReporterSerializer(serializers.ModelSerializer):
    class Meta:
        model = Reporter
        fields = ['id', 'full_name', 'keyword']

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ['id', 'pub_date', 'headline', 'content', 'reporter']

step3: view

根据需求进行处理,实现 CURD - (create、update、retrieve、delete) 操作,DRF 都有对应的 viewset,非复杂性功能的实现可以直接框架提供的类 详见DRF官方文档

from rest_framework import generics
from news.models import Reporter, Article
from news.serializer import ReporterSerializer, ArticleSerializer


class ReporterViewSet(generics.ListCreateAPIView, generics.UpdateAPIView):
	"""
	该视图实现 Reporter model 的 CUR
	"""
    queryset = Reporter.objects.all()
    serializer_class = ReporterSerializer
    lookup_field = 'id'

    def put(self, request, *args, **kwargs):
        setattr(self, 'kwargs', request.data)
        return self.update(request, *args, **kwargs)


class ArticleViewSet(generics.ListCreateAPIView):
	"""
	该视图实现 Article model 的 CR
	"""
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

    def get_serializer(self, *args, **kwargs):
        """ if an array is passed, set serializer to many """
        if isinstance(kwargs.get('data', {}), list):
            kwargs['many'] = True
        return super(ArticleViewSet, self).get_serializer(*args, **kwargs)

step4: url

请求 url

个人推荐在应用下接口比较多的情况下添加 urls.py 文件

  1. 在应用下的 urls.py 文件下添加接口;
  2. 在工程下的 urls.py 文件下将对应应用 urls.py 文件包括进去。
    在这里插入图片描述

应用urls.py添加

# news/urls.py
from django.conf.urls import url
from news.views import ReporterViewSet, ArticleViewSet

urlpatterns = [
    url('^reporter$', ReporterViewSet.as_view(), name='reporter'),
    url('^article', ArticleViewSet.as_view(), name='article'),
]

工程urls.py添加

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('news/', include('news.urls'), name='news')
]

测试接口

完成以上四大步,最简单的接口就完成了,执行 python manage.py runserver即可在本地进行调试,调用。

以测试新建 reporter 接口为例:

Request Headers: Content-Type: application/json
在这里插入图片描述
Response Body:
在这里插入图片描述

参考资料

因为项目需要接触了 Django,趁着周末记录一下也让自己再巩固一下,今天就先写到这了,之后再慢慢的把这段时间积累的东西整理出来,如有什么问题欢迎大家指正。

[1]DRF文档: https://www.django-rest-framework.org/
[2]Django文档: https://docs.djangoproject.com/en/3.0/

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值