前言:
之前转发过一篇文章: https://blog.csdn.net/u012762054/article/details/79521168,但感觉不够简洁于是现在来个简洁版的。
drf api基本步骤:
前提 model已经配置好
class Goods(models.Model):
"""
商品
"""
category = models.ForeignKey(GoodsCategory, verbose_name="商品类目")
goods_sn = models.CharField(max_length=50, default="", verbose_name="商品唯一货号")
name = models.CharField(max_length=100, verbose_name="商品名")
click_num = models.IntegerField(default=0, verbose_name="点击数")
sold_num = models.IntegerField(default=0, verbose_name="商品销售量")
fav_num = models.IntegerField(default=0, verbose_name="收藏数")
goods_num = models.IntegerField(default=0, verbose_name="库存数")
market_price = models.FloatField(default=0, verbose_name="市场价格")
shop_price = models.FloatField(default=0, verbose_name="本店价格")
goods_brief = models.TextField(max_length=500, verbose_name="商品简短描述")
goods_desc = UEditorField(verbose_name=u"内容", imagePath="goods/images/", width=1000, height=300,
filePath="goods/files/", default='')
ship_free = models.BooleanField(default=True, verbose_name="是否承担运费")
goods_front_image = models.ImageField(upload_to="goods/images/", null=True, blank=True, verbose_name="封面图")
is_new = models.BooleanField(default=False, verbose_name="是否新品")
is_hot = models.BooleanField(default=False, verbose_name="是否热销")
add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")
class Meta:
verbose_name = '商品'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class GoodsCategory(models.Model):
"""
商品类别
"""
CATEGORY_TYPE = (
(1, "一级类目"),
(2, "二级类目"),
(3, "三级类目"),
)
name = models.CharField(default="", max_length=30, verbose_name="类别名", help_text="类别名")
code = models.CharField(default="", max_length=30, verbose_name="类别code", help_text="类别code")
desc = models.TextField(default="", verbose_name="类别描述", help_text="类别描述")
category_type = models.IntegerField(choices=CATEGORY_TYPE, verbose_name="类目级别", help_text="类目级别")
parent_category = models.ForeignKey("self", null=True, blank=True, verbose_name="父类目级别", help_text="父目录",
related_name="sub_cat")
is_tab = models.BooleanField(default=False, verbose_name="是否导航", help_text="是否导航")
add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")
class Meta:
verbose_name = "商品类别"
verbose_name_plural = verbose_name
def __str__(self):
return self.name
-
继承某个GenericView,重写里面的某个方法,最大的是get、post、put、patch、delete这些方法,然而并不推荐(应该重写mixin里面的方法)
-
实现一个serilizer,json化response
-
写一个url
api的demo,具体细节之后的博客会详细讲解
1、继承某个Genricview,重写对应方法
class GoodsListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
"""
商品列表页, 分页, 搜索, 过滤, 排序
"""
# throttle_classes = (UserRateThrottle, )
queryset = Goods.objects.all() #重点
serializer_class = GoodsSerializer #重点
pagination_class = GoodsPagination
# authentication_classes = (TokenAuthentication, )
filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
filter_class = GoodsFilter
search_fields = ('name', 'goods_brief', 'goods_desc')
ordering_fields = ('sold_num', 'shop_price')
def retrieve(self, request, *args, **kwargs): #重写部分,也有可能是其他部分重写
instance = self.get_object()
instance.click_num += 1
instance.save()
serializer = self.get_serializer(instance)
return Response(serializer.data)
2、实现一个serilizer,json化response
from rest_framework import serializers
class GoodsSerializer(serializers.ModelSerializer):
category = CategorySerializer() #有下级商品分类
images = GoodsImageSerializer(many=True)
class Meta:
model = Goods
fields = "__all__"
class CategorySerializer(serializers.ModelSerializer):
sub_cat = CategorySerializer2(many=True)
class Meta:
model = GoodsCategory
fields = "__all__"
3、写一个url
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
#配置goods的url
router.register(r'goods', GoodsListViewSet, base_name="goods")
urlpatterns = [
url(r'^', include(router.urls)), #重点
]
作为写框架的人,需要考虑的还有那些?
每个项目总有第一个人做基础构架,这个时候就不是仅仅实现一个api就ok了,你需要考虑跟多的事情,包括
-
统一的异常处理
-
api权限
-
统一的参数校验
-
缓存如何可以做的更简单统一 【可以使用redis做缓存。当然也可以用drf缓存,后面有空会补一个这样的文章】
-
认证 【drf 自带或者jwt】其中drf 为django restful framwork jwt为 json web token
-
统一的查询过滤
-
代码分层