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 serializersclass 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 ModelViewSetfrom .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