[Django rest-framework] 2-ModelSerializers
将上一节中SnippetSerializer继承的父类换为serializers.ModelSerializer
修改代码为:
class SnippetSerializer(serializers.ModelSerializer): class Meta: model = Snippet fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
打开Django shell
python manage.py shell
执行
from snippets.serializers import SnippetSerializer serializer = SnippetSerializer() print(repr(serializer)) # SnippetSerializer(): # id = IntegerField(label='ID', read_only=True) # title = CharField(allow_blank=True, max_length=100, required=False) # code = CharField(style={'base_template': 'textarea.html'}) # linenos = BooleanField(required=False) # language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')... # style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')...
很神奇的只用了两行代码就实现了上一节的功能
将view中的代码改为
# Create your views here. @csrf_exempt def snippet_list(request): """ list all snippets or create a snippet :param request: :return: """ if request.method == 'GET': snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets,many=True) return JsonResponse(serializer.data,safe=False) elif request.method == 'POST': data = JSONParser().parse(request) serializer = SnippetSerializer(data=data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data, status=201) else: return JsonResponse(serializer.errors, status=400) @csrf_exempt def snippet_detail(request, pk): try: snippet = Snippet.objects.get(pk=pk) except: return HttpResponse(404) if request.method == "GET": serializer = SnippetSerializer(snippet) return JsonResponse(serializer.data) if request.method == "PUT": data = JSONParser().parse(request) serializer = SnippetSerializer(data=data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data) else: return JsonResponse(serializer.errors, status=400) if request.method == 'DELETE': snippet.delete() return HttpResponse(204)
url 修改为
urlpatterns = [ url(r'^snippets/$', views.snippet_list), url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail), ]
当然,tutorail中的url修改为
urlpatterns = [ url(r'^', include('snippets.urls')), ]
打开postman试试吧
GET: /snippets/
[{"id": 1, "title": "", "code": "foo=\"bar\"\n", "linenos": false, "language": "python", "style": "friendly"},
{"id": 3, "title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly"},
{"id": 4, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"}, {"id": 5, "title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly"}, {"id": 6, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"}, {"id": 7, "title": "", "code": "foo = \"bar\"\n", "li......
GET中的 return JsonResponse(serializer.data,safe=False)这一句中的safe必须设置为False,因为我们返回的并不是一个dict而是一个数组
POST: /snippets/
request body
{}
response
{"code": ["This field is required."]}
POST: /snippets/
request body
{"code":"console.log('ok')"}
response
{"id": 18, "title": "", "code": "console.log('ok)", "linenos": false, "language": "python", "style": "friendly"}
修改serializer.py中meta元类中的fields包含的字段看到,这里定义了需要关注的字段
删除id
GET: /snippets/
[{"title": "", "code": "foo=\"bar\"\n", "linenos": false, "language": "python", "style": "friendly"},
{"title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly"},
{"title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"},
{"title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly"}, {"title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"},...
着实很方便
但实际情况中,有时候数据库定义的字段和我们想返回的字段名不同,比如id我们想返回为userId;
有时候我们不想返回所有字段,比如我们只想返回title 和 code
目前就不知道改怎么办了,看看下一节能不能解决这个问题
参考资料:http://www.django-rest-framework.org/tutorial/1-serialization/#using-modelserializers