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')  # 定義這幾列數據是只讀的

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM