最初使用django,搞的是前后端不分离的项目,后来搞前后端分离又直接用的DRF,突然心血来潮使用django框架,想要返回json数据时却遇到了问题。
随便写了个demo,如下:
models
class Book(models.Model):
name = models.CharField(verbose_name='书名', max_length=50)
category = models.CharField(verbose_name='类别', max_length=30)
create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
class Meta:
verbose_name = '书籍'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
views
import json
from django.core import serializers
from django.http import JsonResponse
from book.models import Book
def get_books(request):
books = Book.objects.all()
books_json = json.loads(serializers.serialize('json', books))
data = {
'code': '001',
'data': books_json
}
return JsonResponse(data)
url
from django.urls import path
from .views import get_books
urlpatterns = [
path('all_books/', get_books),
]
根url
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('book/', include('book.urls'))
]
WTF?显示的model等信息,我完全不想要啊
BUT 我搜了一下也没啥好方法————于是我又使用了drf搞一下
首先安装djangorestframework,注册
创建serializer文件
from rest_framework import serializers
from book.models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = "__all__"
view---之前的没删,做对比吧
import json
from django.core import serializers
from django.http import JsonResponse
from rest_framework import viewsets
from book.models import Book
from book.serializers import BookSerializer
def get_books(request):
books = Book.objects.all()
books_json = json.loads(serializers.serialize('json', books))
data = {
'code': '001',
'data': books_json
}
return JsonResponse(data)
class BookViewSet(viewsets.ModelViewSet):
serializer_class = BookSerializer
def get_queryset(self):
return Book.objects.all()
根url
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from book.views import BookViewSet
router = routers.DefaultRouter()
router.register(r'books', BookViewSet, basename='books')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('book/', include('book.urls'))
]
浏览器运行结果:
好了,舒服了,又回到DRF了....囧
当然如果想要同时返回自定义状态码code或者msg,也很简单
如
在settings.py中加上配置信息
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'utils.exceptions.exception_handler', # 异常处理
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',
'DEFAULT_RENDERER_CLASSES': (
'utils.returnRenderer.MyJSONRenderer', # 自定义返回附加信息
),
}
其中可以简单的定义一下returnRenderer.py文件
from rest_framework.renderers import JSONRenderer
class MyJSONRenderer(JSONRenderer):
"""
{
code:0
msg:'请求成功',
data:''
}
"""
def render(self, data, accepted_media_type=None, renderer_context=None):
# 返回来的数据中包含了code和mag,可以通过pop拿出来
if isinstance(data, dict):
code = data.pop('code', 200)
msg = data.pop('msg', '请求成功')
else:
code = 0
msg = '请求成功'
res = {
'code': code,
'msg': msg,
'data': data
}
return super().render(res, accepted_media_type=None, renderer_context=None)
贴一个之前写的demo
class LatestBooksViewSet(GenericViewSet, ListModelMixin, RetrieveModelMixin):
serializer_class = BookSerializer
filter_backends = (DjangoFilterBackend,)
filter_class = BookFilter
def get_queryset(self):
return Book.objects.all().order_by('-book_date')
def retrieve(self, request, *args, **kwargs):
try:
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
except:
data = {
'code': 1010,
'msg': '图书不存在'
}
return Response(data)