Django如何实现序列化?

我们知道WEB应用模式分为两种:前后端不分离和前后端分离的模式。所谓前后端不分离就是在前端页面看到的效果都是由后端控制的,由后端页面渲染或者重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高,这种模式比较适合纯网页应用,但是后端对接APP时,APP可能并不需要后端返回一个HTML网页,而仅仅是数据本身,所以后端原本返回网页的接口不在适用前端APP应用,为了对接APP后端还需再开发一套接口。

而前后端分离之后后端仅返回前端所需要的数据,不再渲染HTML页面,不再控制前端的效果,只要前端用户看到什么效果,从后端请求的数据如何加载到前端中,都由前端自己决定,网页有网页自己的处理方式,APP有APP的处理方式,但无论哪种前端所需要的数据基本相同,后端仅需开发一套逻辑对外提供数据即可,在前后端分离的应用模式中,前端与后端的耦合度相对较低。在前后端分离的应用模式中,我们通常将后端开发的每一视图都成为一个接口或者API,前端通过访问接口来对数据进行增删改查。那么问题来了、我们如何通过Django从后端返回JSON或者API格式的接口呢?

什么是DRF?

要从后端返回JSON或者API格式的接口、就必须讲到序列化。在开始讲解如何通过Django实现序列化之前我们先一起来看看什么是DRF。Django Rest Framework 是一个强大且灵活的工具包,用以构建Web API。 Django REST Framework可以在Django的基础上迅速实现API,并且自身还带有WEB的测试页面,可以方便的测试自己的API。

序列化和反序列化可以复用的好处如下: 增:效验请求数据>执行反序列化过程>保存数据库>将保存的对象序列化并返回; 删:判断要删除的数据是否存在.>执行数据库删除; 改:判断要修改的数据是否存在>效验请求的参数>执行反序列化过程>保存数据库>将保存的对象序列化并返回; 查:查询数据库>将数据序列化并返回; 特点: 1.提供了定义序列化器 Serializer 的方法,可以快速根据 Django ORM 或者其他库自动序列化/反序列化; 2.提供了丰富的类视图\MIXIN扩展类,简化视图的编写; 3.丰富的定制层级:函数视图\类视图\试图结合到自动生成API,满足各种需要; 4.多种身份认证和权限认证方式的支持; 5.内置了限流系统; 6.直观的API web界面; 7.可扩展性 , 插件丰富;

通过 Django json.dumps实现序列化

Django默认有一个序列化的方法 Json.Dumps。具体代码如下:

from django.views.generic.base import View
from goods.models import Goods


class GoodsListView(View):
    def get(self, request):
        json_list = []
        goods = Goods.objects.all()[:10]
        for good in goods:
            json_dict = {}
            json_dict["name"] = good.name
            json_dict["shop_price"] = good.shop_price
            json_dict["market_price"] = good.market_price
            json_list.append(json_dict)
        from django.http import HttpResponse
        import json
        return HttpResponse(json.dumps(json_list), content_type="application/json")

    def post(self, request):
        pass

然后我们去URL里面引入上面的View:

from django.contrib import admin
from django.conf.urls import url
from MxOnline.settings import MEDIA_ROOT
from django.views.static import serve

from goods.views import GoodsListView

urlpatterns = [
    url('admin/', admin.site.urls),

    # 配置图片访问路径
    url(r'^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}),

    # 商品列表页
    url(r'goods/$', GoodsListView.as_view(), name="goods_list")
]

然后我们就可以启动项目去访问http://127.0.0.1:8000/goods这个接口了。可以看到、我们已经通过简单的示例实现了Goods商品的序列化并返回了JSON格式的数据(请自行安装JSONVIEW插件):

img

虽然我们上面通过Django实现了Goods的序列化、但是这里面还有很多问题没有解决。比如 image、datetime,外键等字段通过json.dumps实现序列化都会报错的;字段比较多的时候、特别麻烦也容易出错;上面的代码写起来和维护起来都比较麻烦。那么,有没有更简便的方法呢?有的,Django给我们提供了一个方法:model_to_dict。model_to_dict 可以将model转换成一个dict、具体代码如下:

from django.views.generic.base import View
from goods.models import Goods


class GoodsListView(View):
    def get(self, request):
        json_list = []
        goods = Goods.objects.all()[:10]
        # for good in goods:
        #     json_dict = {}
        #     json_dict["name"] = good.name
        #     json_dict["shop_price"] = good.shop_price
        #     json_dict["market_price"] = good.market_price
        #     json_list.append(json_dict)

        from django.forms.models import model_to_dict
        for good in goods:
            json_dict = model_to_dict(good)
            json_list.append(json_dict)
        from django.http import HttpResponse
        import json
        return HttpResponse(json.dumps(json_list), content_type="application/json")

    def post(self, request):
        pass

这样我们就不用像上面一样把一个个字段单独提取出来、方便很多、代码量也很多少。但是新的问题又出现了:model_to_dict 不能把所有的字段都序列化。这里我们通过PyCharm的单步调试可以看到、model_to_dict 确实把数据都取了出来,但是我们通过点击F9把程序执行完之后就可以看到错误页面了。页面提示我们ImageFieldFile不是一个JSON序列化对象:

img

img

其实,Django为我们提供了一个专门进行序列化的方法 from django.core import serializers,示例代码如下:

from django.views.generic.base import View
from goods.models import Goods


class GoodsListView(View):
    def get(self, request):
        json_list = []
        goods = Goods.objects.all()[:10]
        # for good in goods:
        #     json_dict = {}
        #     json_dict["name"] = good.name
        #     json_dict["shop_price"] = good.shop_price
        #     json_dict["market_price"] = good.market_price
        #     json_list.append(json_dict)

        from django.forms.models import model_to_dict
        for good in goods:
            json_dict = model_to_dict(good)
            json_list.append(json_dict)

        import json
        from django.core import serializers
        json_data = serializers.serialize("json", goods)
        from django.http import HttpResponse, JsonResponse
        import json
        return HttpResponse(json_data, content_type="application/json")

    def post(self, request):
        pass

我们再次启动项目并访问 http://127.0.0.1:8000/goods 接口,我们可以看到数据已经成功返回。但是还没完、Django还有没有其他的实现序列化的方法呢?有的。

img

上面我们是通过Django提供的HttpResponse方法完成的HTTP请求,Django除了给我们提供了一个HttpResponse以外,还给我们提供了一个JsonResponse。这里我们为了使代码更加简洁、我们使用JsonResponse来实现序列化:

from django.views.generic.base import View
from goods.models import Goods


class GoodsListView(View):
    def get(self, request):
        json_list = []
        goods = Goods.objects.all()[:10]
        # for good in goods:
        #     json_dict = {}
        #     json_dict["name"] = good.name
        #     json_dict["shop_price"] = good.shop_price
        #     json_dict["market_price"] = good.market_price
        #     json_list.append(json_dict)

        from django.forms.models import model_to_dict
        for good in goods:
            json_dict = model_to_dict(good)
            json_list.append(json_dict)

        import json
        from django.core import serializers
        json_data = serializers.serialize("json", goods)
        json_data = json.loads(json_data)
        from django.http import HttpResponse, JsonResponse
        import json
        # 这里我们必须要设置safe=False这个参数、不然页面会报错的。
        return JsonResponse(json_data, safe=False)

    def post(self, request):
        pass

好了、跟上面一样、我们可以正常拿到数据了。我们现在虽然返回了一个Json、但是这里面还有很多问题没有解决比如输入、检测、序列化的自定义、组合等问题。这些工作就需要我们通过DRF来实现了、那么如何通过DRF实现序列化呢?且听下回分解。

img

img

推荐文章

43条评论

  1. Hello. This article was extremely motivating, particularly since I was browsing for thoughts on this issue last Monday. Priscilla Charlton Teri

  2. Precisely what I was looking for, thanks for posting. Kathy Brant Eldrida

  3. There is an option in the plugin settings to set that. Please check. Virgie Jozef Barram

  4. You are obviously very knowledgeable. You appear to know a lot about this. Interesting content. Some nice points there. Gizela Elliott Rupert

  5. Ahaa, its fastidious discussion about this article here at this webpage, I have read all that, so now me also commenting at this place.| Thea Damon Ashok

  6. Wonderful article! We will be linking to this particularly great content on our site. Keep up the great writing. Roxie Rob Orten

  7. Good blog here! right after reading, i decide to buy a sleeping bag ASAP Angelika Geordie Osy

  8. whoah this blog is wonderful i love reading your posts. Keep up the great work! You know, lots of people are searching around for this info, you could aid them greatly. Lyndell Gill Terzas

  9. Oh, this is such a beautiful card. Love all those red poppies. Thanks for joining us for Viva la Verve! Sibbie Cello Convery

  10. This piece of writing is genuinely a pleasant one it assists new net visitors, who are wishing in favor of blogging. Ruby Gabie Drus

  11. Truly amazing creatures. Loved all of the pictures. Fancy Marlo Angus

  12. You can certainly see your expertise in the article you write. Monah Gibby Gaylor

  13. Appreciate you sharing, great blog article. Want more. Misti Leonardo Kryska

  14. Awesome post. I am a regular visitor of your web site and appreciate you taking the time to maintain the nice site. I will be a frequent visitor for a really long time. Lorne Sim Tracy

  15. So excited to see another one come out. I love reading your books. Joellen Hobard Albert

  16. Одновременно с этим существует и другая сторона формирования и организации высказывания.

  17. Одновременно с этим существует и другая сторона формирования и организации высказывания.

  18. I loved the blog post! I will surely add it to my favorites and visit your post often!

  19. Nice articles bruh! Like and favorite list add!

  20. Nice articles bruh! Like and favorite list add!

  21. Nice articles bruh! Like and favorite list add!

  22. Nice articles bruh! Like and favorite list add!

  23. En ucuz fiyata en organik paketler ile hizmet vermekteyiz.

  24. What’s up every one, here every one is sharing these knowledge, so it’s nice to read this web
    site, and I used to visit this blog everyday.

  25. We are a group of volunteers and opening a new scheme in our community.
    Your website provided us with valuable info to work on. You’ve done a formidable job and our entire community will be thankful to you.

  26. Nice blog! Thanks you all star articles good story!

  27. Hello there! Do you know if they make any
    plugins to assist with Search Engine Optimization? I’m
    trying to get my blog to rank for some targeted keywords but I’m not seeing very
    good success. If you know of any please share. Kudos!

  28. I am actually grateful to the owner of this web site who has shared
    this wonderful paragraph at here.

  29. I like what you guys are usually up too. This sort of clever work
    and coverage! Keep up the superb works guys I’ve incorporated
    you guys to my blogroll.

  30. I’m gone to tell my little brother, that he should also pay a quick visit this blog on regular basis to obtain updated from latest
    news update.

  31. you are best, very nicee blog yoour amazing site.

  32. Thanks in support of sharing such a pleasant thinking, paragraph is
    nice, thats why i have read it completely

  33. your articles are very good and your blog site iss really good

  34. What’s up colleagues, how is all, and what you would like to say concerning
    this article, in my view its truly awesome in support of me.

  35. your articles are very good and your blog site is reaally good

  36. your blogss contain real information and you guys post great articles. we are grateful to you.

  37. I reeally like the statuses and articles you share and your blogs.

  38. I’m curious to find out what blog system you’re utilizing?
    I’m experiencing some minor security problems with my latest site and
    I would like to find something more safe. Do you have any recommendations?

  39. youur blogs contain real information and you guys post great articles. we are grateful to you.

  40. yoour articles are very nice and well informative. thanks.

  41. Howdy, I believe your site could possibly be having browser compatibility problems.
    Whenever I look at your site in Safari, it looks fine but when opening in IE, it’s got some overlapping issues.
    I just wanted to provide you with a quick heads up! Besides that, excellent website!

  42. Link exchange is nothing else however it is simply placing the other
    person’s weblog link on your page at suitable place and other person will also do similar in favor of you.

  43. I all the time emailed this webpage post page to all my contacts, since if like to read it then my contacts will too.

发表评论

邮箱地址不会被公开。 必填项已用*标注