前言:
最近工作中需要用到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') # 定義這幾列數據是只讀的