DjandoRestFramework

编程

RESTful规范

REST风格

  • 资源 网页中能看到的都是资源
  • URI 统一资源标识符
  • URL 统一资源定位符
  • 统一资源接口,对资源的操作根据HTTP请求方式的不同来进行不同操作, 遵循HTTP请求方式的语义
  • 前后端传输的是资源的表述
  • 展现的是资源的状态

RESTful架构

  • 核心思想

    • 面向资源去编程,url中尽量名词不要用动词
    • 根据HTTP请求方式的不同对资源进行不同的操作

  • 在url中体现的

    • 体现版本

      	https://v2.bootcss.com/

      https://bootcss.com/v2

    • 体现是否是API

      	https://v2.bootcss.com/api

    • 有过滤条件

      	https://v2.bootcss.com/course?page=1

    • 尽量用https

  • 在返回值中

    • 携带状态码
    • 返回值

      • get 查询,返回查看的所有或者单条数据
      • post 新增,返回新增的这条数据
      • put 修改,返回更新的这条数据
      • delete 删除,返回值空

    • 携带错误信息
    • 携带超链接

DRF开发步骤

一、安装REST framework

pip install djangorestframework

添加 rest_framework 到你的 INSTALLED_APPS 设置中

INSTALLED_APPS = (

...

"rest_framework",

)

二、数据模型示例

class Industry(models.Model):

name = models.CharField("行业名称", max_length=150, help_text="行业名称")

slug = models.SlugField(max_length=150, unique=True, default=None, editable=False)

class Customer(models.Model):

name = models.CharField("客户名称", max_length=500, help_text="客户/公司全称", unique=True)

projects = models.ManyToManyField(Solution, verbose_name="客户当前项目", blank=True, related_name="customer")

qq = models.CharField("QQ", max_length=64, unique=True, blank=True, null=True, help_text="负责人QQ号码")

industry = models.ForeignKey(Industry, verbose_name="所属行业", related_name="customers", blank=True, null=True,

on_delete=models.SET_NULL)

it_persons = models.CharField("IT负责人", max_length=32, blank=True, null=True)

it_phone = models.BigIntegerField("IT负责人联系电话", blank=True, null=True)

responsible_persons = models.CharField("企业负责人", max_length=32, blank=True, null=True)

rp_phone = models.BigIntegerField("企业负责人联系电话", blank=True, null=True)

status = models.CharField("客户当前意向", choices=ENROLL_STATUS, max_length=64, default=None,

help_text="选择客户当前的意向状态")

source = models.CharField("客户来源", max_length=255, blank=True, null=True)

consult_note = models.TextField("咨询内容", blank=True, null=True, help_text="客户咨询内容")

date = models.DateField("咨询日期", auto_now_add=True)

last_consult_date = models.DateField("最后跟进日期", auto_now_add=True)

next_date = models.DateField("预计再次跟进时间", blank=True, null=True)

address = models.CharField("客户地址", max_length=500, blank=True, null=True)

private = models.BooleanField(verbose_name="是否私户", default=True)

isp = models.CharField("归属运营商", choices=ISP_LIST, max_length=32, default="N/A", )

consultants = models.ManyToManyField(UserProfile, verbose_name="客户经理/技术支撑", blank=True,

related_name="consultants")

business_scope = models.TextField("经营范围", blank=True, null=True)

memo = models.TextField("备注", blank=True, null=True, help_text="备注,客户情况")

三、声明模型的序列化器(serializers.py)

from rest_framework import serializers

class IndustrySerializer(serializers.ModelSerializer):

class Meta:

model = Industry

fields = "__all__"

class CustomerSerializer(serializers.ModelSerializer):

# 自定义展示的数据结构,只读,只用于展示

projects_info = serializers.SerializerMethodField(read_only=True) # 多对多

def get_projects_info(self, obj):

projects_queryset = obj.projects.all()

if projects_queryset:

return [

{"id": project.id, "title": project.title, "industry": project.industry.name, "status": project.status}

for project in projects_queryset]

else:

return None

industry_info = serializers.SerializerMethodField(read_only=True) # 一对多

def get_industry_info(self, obj):

if obj.industry:

industry_obj = obj.industry

return {"id": industry_obj.id, "name": industry_obj.name}

else:

return None

consultants_info = serializers.SerializerMethodField(read_only=True) # 多对多

def get_consultants_info(self, obj):

consultants_queryset = obj.consultants.all()

if consultants_queryset:

return [{"id": consultant.id, "name": consultant.name} for consultant in consultants_queryset]

else:

return None

class Meta:

model = Customer

fields = "__all__"

# 外键关联关系层级

# depth = 1

# 指定的字段只用于写入,展示时不显示

extra_kwargs = {"projects": {"write_only": True}, "industry": {"write_only": True},

"consultants": {"write_only": True}}

四、编写urls及views

urlpatterns = [

path("crm/industry/<int:pk>",

views.IndustryView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),

path("crm/customer", views.CustomerView.as_view({"get": "list", "post": "create"})),

path("crm/customer/<int:pk>",

views.CustomerView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),

]

from rest_framework.viewsets import ModelViewSet

from .serializers import IndustrySerializer, CustomerSerializer

class IndustryView(ModelViewSet):

queryset = Industry.objects.all()

serializer_class = IndustrySerializer

class CustomerView(ModelViewSet):

queryset = Customer.objects.all()

serializer_class = CustomerSerializer

使用DRF的DefaultRouter自动生成url路由

修改 urls.py 文件:

# 帮助我们生成带参数的路由

from rest_framework.routers import DefaultRouter

# 实例化DefaultRouter对象

router = DefaultRouter()

# 注册我们的路由以及视图

router.register(r"^crm/industry", views.IndustryView)

router.register(r"^crm/customer", views.CustomerView)

urlpatterns = []

urlpatterns += router.urls

配置后,DRF将为我们自动生成上一个例子一样的路由

在URL中使用DRF的版本控制

添加如下配置到你的 INSTALLED_APPS 设置中

REST_FRAMEWORK = {

"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",

"DEFAULT_VERSION": "v1", # 默认的版本

"ALLOWED_VERSIONS": ["v1", "v2"], # 有效的版本

"VERSION_PARAM": "version", # 版本的参数名与URL conf中一致

}

修改注册的路由配置

router.register(r"^(?P<version>[v1|v2]+)/crm/industry", views.IndustryView)

router.register(r"^(?P<version>[v1|v2]+)/crm/customer", views.CustomerView)

URL访问方式如:http://127.0.0.1:8000/v2/crm/industry/

修改 views.py,在URL获取版本号并根据不同的版本号进行不同的处理

class IndustryView(ModelViewSet):

queryset = Industry.objects.all()

serializer_class = IndustrySerializer

def list(self, request, *args, **kwargs):

if request.version == "v2": # 拿到版本号,对不同版本进行不同处理

self.queryset = Industry.objects.filter(name="政务").all()

self.serializer_class = IndustrySerializer

return super(IndustryView, self).list(request, *args, **kwargs)

...

Django REST framework中文文档

以上是 DjandoRestFramework 的全部内容, 来源链接: utcz.com/z/511251.html

回到顶部