zoukankan      html  css  js  c++  java
  • Django rest_framework 实用技巧

    前言:

      最近工作中需要用到Django rest_framework框架做API, 边学边写,记录了一些实际工作中需要用到的功能,不是很全也不系统,以后需要什么功能可以在这查询. 后续还会更新其它的用法

      1 ####################################################################
      2 ########安装和简单使用
      3     ###### 准备工作
      4         pip install rest_framework  # 安装
      5 
      6         INSTALLED_APPS = (
      7             ...
      8             'rest_framework',   # 将其加入app列表内
      9         )
     10 
     11 
     12     ###### urls.py 
     13         from django.conf.urls import include, url  # 引入include二级路由, url
     14         from django.contrib import admin           # admin模块
     15         from rest_framework import routers         # 导入api路由 !
     16         import app1         # 导入app1
     17 
     18         router = routers.DefaultRouter()           # 获取api路由对象
     19         router.register(r'users', app1.SpecialGiftViewSet)# 注册路由到指定的ViewSet类
     20 
     21         urlpatterns = [
     22             url(r'^admin/', include(admin.site.urls)),  
     23             url(r'^', include(router.urls)),       # 设置api路由转发
     24         ]
     25 
     26 
     27     ###### app1/serializers.py
     28         from rest_framework import serializers  # api接口用于序列化 model 的类
     29         from app1.models import SpecialGift     # 自定义的要提供api的model类
     30 
     31         class UserSerializer(serializers.HyperlinkedModelSerializer):  # 序列化这个表的类
     32             class Meta:
     33                 model = SpecialGift
     34                 fields = ('url', 'username', 'email', 'is_staff')      # 验证字段可以省略!
     35 
     36         ---------参数扩展-----------
     37         # HyperlinkedModelSerializer 是建立超链接关系就是外健使用 "goods": "http://127.0.0.1:8080/goods/1/"
     38         # ModelSerializer  建立主健关系在json数据中表现为 'goods': 1
     39         # ReadOnlyModelViewSet  未知
     40      
     41 
     42     ####### app1/views.py 内容
     43         from rest_framework import routers, serializers, viewsets      # 分别为api的路由, 序列化, viewsets
     44         from app1.serializers import SpecialGiftSerializer           # 引入处理序列化的类
     45         from rest_framework.permissions import AllowAny, IsAuthenticated, IsAdminUser  # 用于指定权限, 所有人, 登录用户, 管理员
     46         from app01.models import SpecialGift                  # 引入models类
     47         from django.utils import timezone    # 按时区的,当前时间
     48         # from rest_framework import response
     49 
     50         class SpecialGiftViewSet(viewsets.ReadOnlyModelViewSet):
     51             queryset = SpecialGift.objects.all().order_by('-created')    # 指定默认查询方式, 按创建时间倒序
     52             serializer_class = SpecialGiftSerializer                  # 指定处理序列化的类
     53             permission_classes = [AllowAny]                        # 指定权限 AllowAny 为所有人
     54 
     55             def get_queryset(self):  # 过滤函数
     56                 return self.queryset.filter(end_time__gt=timezone.now())  # 过滤当前时间以前的记录
     57 
     58 
     59 
     60     ###### app1/models.py 中写入模型定义
     61         from django.utils.translation import ugettext_lazy as _  # Django国际化翻译
     62         
     63         class SpecialGift(models.Model):
     64         title = models.CharField(max_length=64)
     65         image = VersatileImageField(_("gift_image"),
     66                                     max_length=255,
     67                                     upload_to=generate_upload_filename,
     68                                     )
     69         min_money = models.DecimalField(_("min_money"), max_digits=7, decimal_places=2, validators=[MinValueValidator(0)])
     70         price = models.DecimalField(_("price"), max_digits=7, decimal_places=2, validators=[MinValueValidator(0)],
     71                                     default=29.9)
     72         end_time = models.DateTimeField()
     73 
     74         def __unicode__(self):
     75             return self.title
     76 
     77 
     78     ###### app1/admin.py 中配置管理界面
     79         from django.contrib import admin
     80         from app1.models import SpecialGift
     81 
     82         admin.site.register(SpecialGift)  # 简单注册每行只显示对象名
     83 
     84         # 装饰器注册!
     85         @admin.register(SpecialGift)
     86         class SpecialGiftAdmin(admin.ModelAdmin):
     87             list_display = ('title', 'image', 'min_money', 'price', 'end_time')  # 显示为表结构包括所有的列
     88             search_fields = ['title']  # 出现搜索框, 指定搜索哪一列字段
     89 
     90         # 在django中我们没有创建对数据库的查询操作和页面返回,但是调用rest framework标准的api接口我们就可以直接从数据库中查询到数据,增删改查都是可以的!实现起来如此简单!
     91 
     92 
     93     ###### setting.py配置
     94     REST_FRAMEWORK = {
     95         'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',),
     96         'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
     97         'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
     98         'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning',
     99         'DEFAULT_VERSION': '160201',
    100         'PAGE_SIZE': 10,   # 每页10条数据
    101         'DEFAULT_AUTHENTICATION_CLASSES': (
    102             'rest_framework.authentication.SessionAuthentication',
    103             'rest_framework.authentication.TokenAuthentication',
    104         ),
    105     }
    106 
    107 
    108 
    109 
    110 #######################################################################
    111 # 为查询到的数据增加相关联的字段!! 正查!!
    112 #######################################################################
    113     # models.py
    114     class Goods(models.Model):
    115         name = models.CharField(max_length=128)
    116         price = models.CharField(max_length=56, blank=True, null=True)
    117 
    118 
    119     class Index(models.Model):
    120         goods = models.ForeignKey(Goods, verbose_name="Goods")
    121         start_at = models.DateTimeField()
    122         end_at = models.DateTimeField()
    123 
    124 
    125     # serializers.py
    126     class GoodsSerializers(serializers.HyperlinkedModelSerializer):
    127         class Meta:
    128             model = Goods
    129             fields = ('name', 'price')
    130 
    131 
    132     class IndexSerializers(serializers.HyperlinkedModelSerializer):
    133         name = serializers.ReadOnlyField(source='goods.name')    # 增加外健的字段
    134         price = serializers.ReadOnlyField(source='goods.price')  # 添加外健的字段 
    135 
    136         class Meta:
    137             model = Index
    138             fields = ('goods', 'start_at', 'end_at', 'name', 'price')
    139 
    140 
    141     # views.py
    142     class IndexViewSet(viewsets.ReadOnlyModelViewSet):
    143         queryset = Index.objects.all()
    144         serializer_class = IndexSerializers
    145 
    146 
    147     class GoodsViewSet(viewsets.ReadOnlyModelViewSet):
    148         queryset = Goods.objects.all()
    149         serializer_class = GoodsSerializers
    150 
    151     # 结果! 商品本来只有一个url接口要起得到详细还得再查询一次.现在将详细直接加入数据中方便很多!
    152     {
    153         "count": 2,
    154         "next": null,
    155         "previous": null,
    156         "results": [
    157             {
    158                 "goods": "http://127.0.0.1:8080/goods/1/",
    159                 "start_at": "2017-01-03T14:22:55Z",
    160                 "end_at": "2017-01-03T14:22:56Z",
    161                 "name": "book",
    162                 "price": "18.5"
    163             },
    164             {
    165                 "goods": "http://127.0.0.1:8080/goods/2/",
    166                 "start_at": "2017-01-03T14:23:04Z",
    167                 "end_at": "2017-01-03T14:23:05Z",
    168                 "name": "pen",
    169                 "price": "34.5"
    170             }
    171         ]
    172     }
    173 
    174 
    175 
    176 
    177 ################################################################################
    178 ###### api嵌套查询, 查询外健对象的具具体内容, 而不是只显示iD
    179 ###### 正查例子
    180     class Column(models.Model):
    181         name = models.CharField(u'类型名称', max_length=256)
    182         slug = models.CharField(u'类型网址', max_length=256, db_index=True)
    183         intro = models.TextField(u'类型简介', default='')
    184 
    185     class Article(models.Model):
    186         column = models.ManyToManyField(Column, verbose_name=u'分类')
    187         genre = models.SmallIntegerField(u'文本<图片<视频', choices=ARTICLE_GENRE, default=ARTICLE_TXT,
    188                                          help_text=u'文章所属类型. 优先级别视频大于图片大于文本')
    189 
    190     # article的models里面有多对多的外健column字段
    191     class ColumnSerializer(serializers.ModelSerializer):
    192         class Meta:
    193             model = Column
    194 
    195     class ArticleSerializer(serializers.ModelSerializer):
    196         column = ColumnSerializer(many=True, read_only=False)  # 定义和外健字段重名的字段并为其指定序列化类
    197         class Meta:
    198             model = Article
    199             fields = ('title', 'column')   # 定义只操作这两列数据(如果不定义fields则默认为全部字段, 如果定义fields则
    200                                            # _必须包含本类中定义的column字段, 否则报错)
    201 
    202     class ArticleViewSet(viewsets.ReadOnlyModelViewSet):        # view.py
    203             queryset = Article.objects.all()                    # 查询
    204             serializer_class = ArticleSerializer                # 指定序列化类
    205 
    206 
    207 
    208 
    209 
    210 ###### 反查例子:
    211     # 还用上面的models为例再加个评论表, 外健分别为User, Article, 通过Article查询评论的内容如下
    212     class Comment(models.Model):
    213         owner = models.ForeignKey('auth.User')
    214         article = models.ForeignKey(Article, related_name='comments')  # 注意反查名
    215         content = models.CharField(u'评论内容', max_length=1024)
    216         flag = models.BooleanField(u'标记', default=True)
    217         updated = models.DateTimeField(auto_now=True)
    218         created = models.DateTimeField(auto_now_add=True)
    219 
    220     class CommentSerializer(serializers.ModelSerializer):   # 为此表定义序列化类
    221         class Meta:
    222             model = Comment
    223 
    224     class ArticleSerializer(serializers.ModelSerializer):
    225         column = ColumnSerializer(many=True, read_only=False)
    226         comments = CommentSerializer(many=True, read_only=False)  # 使用反查名指定序列化类
    227         class Meta:
    228             model = Article
    229 
    230     class ArticleViewSet(viewsets.ReadOnlyModelViewSet):    # view.py
    231         queryset = Article.objects.all()                    # 查询
    232         serializer_class = ArticleSerializer                # 指定序列化类
    233         def get_queryset(self):                        # 过滤函数
    234             return self.queryset.filter(end_time__gt=timezone.now())
    235 
    236 
    237 
    238 
    239 
    240 ################################################################################
    241 ######关于class Meta的其它功能
    242     class ArticleSerializer(serializers.ModelSerializer):
    243         column = ColumnSerializer(many=True, read_only=False)  # 定义和外健字段重名的字段并为其指定序列化类
    244         class Meta:
    245             model = Article          # 定义对应的model
    246 
    247             exclude = ('id', )        # 定义排除这几列数据
    248 
    249             fields = ('title', 'column')   # 定义只操作这两列数据(如果不定义,默认是全部数据)
    250 
    251             read_only_fields = ('id', 'user')  # 定义这几列数据是只读的
  • 相关阅读:
    多线程系列二:原子操作
    多线程系列一:线程基础
    java面试题——高级篇
    SpringMVC系列(十六)Spring MVC与Struts2的对比
    SpringMVC系列(十五)Spring MVC与Spring整合时实例被创建两次的解决方案以及Spring 的 IOC 容器和 SpringMVC 的 IOC 容器的关系
    Android IOS WebRTC 音视频开发总结(三六)-- easyRTC介绍
    Android IOS WebRTC 音视频开发总结(三五)-- chatroulette介绍
    Android IOS WebRTC 音视频开发总结(三四)-- windows.20150706
    Android IOS WebRTC 音视频开发总结(三三)-- Periscope介绍
    Android IOS WebRTC 音视频开发总结(三二)-- WebRTC项目开发建议
  • 原文地址:https://www.cnblogs.com/zyu911/p/6254402.html
Copyright © 2011-2022 走看看