• django跨表联查传输数据到前端


    需求:通过一对多的表关联字段,拿到多的一方所有数据,再通过序列化传到前端页面!
    
    
    models.py
    
    
    class Infomation(BaseModel):
        title = models.CharField(max_length=64, verbose_name='资讯标题')
        title_photo = models.ImageField(upload_to='title_photo', verbose_name='资讯封面', max_length=255, null=True, blank=True)
        info_type = models.ForeignKey(to='Info_Type', verbose_name='资讯所属类型', on_delete=models.CASCADE, related_name='info')
    
        # @property
        # def photos(self):
        #     photo_list = self.detail_photo.all()
        #     return [photo_obj.id for photo_obj in photo_list]
        
        class Meta:
            db_table = 'freedom_infomation'
            verbose_name = '资讯'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.title
    
    class Info_photo(BaseModel):
        photo = models.ImageField(upload_to='info_photo', max_length=255, verbose_name='资讯的图片', null=True, blank=True)
        info = models.ForeignKey(to='Infomation', verbose_name='所属的资讯', related_name='detail_photo',
                                 on_delete=models.CASCADE)
        class Meta:
            db_table = 'freedom_info_photo'
            verbose_name = '资讯的图片'
            verbose_name_plural = verbose_name
    
    上述为模型层,Infomation表与Info_photo表是一对多相互关联的!
    
    
    
    views.py
    
    from rest_framework.generics import ListAPIView
    class InformateAPIView(ListAPIView):
        queryset = Infomation.objects.filter(is_show=True, is_delete=False)
        serializer_class = InformationModelSerializer
    
    上述为视图层,可以直接利用drf的封装的方法,完成数据的查询
    
    
    urls.py
    
    path('information/', views.InformateAPIView.as_view()),
    
    上述为路由层
    
    
    
    
    serializer.py      序列化层
    
    class Info_photomodelSerializer(serializers.ModelSerializer):
        class Meta:
            model = Info_photo
            fields = ['photo','id']
    
    
    
    class InformationModelSerializer(serializers.ModelSerializer):
        detail_photo = Info_photomodelSerializer(many=True)
        class Meta:
            model = Infomation
            fields = [ 'title',  'title_photo', 'create_time', 'id','detail_photo' ]
    
    
    
    
    
    处理的方式有两种:
    第一种:在models.py 里   直接在 表 Infomation 下定义一个类方法:
    
     @property
        def photos(self):
            photo_list = self.detail_photo.all()
            # return [(photo_obj.id,photo_obj.photo) for photo_obj in photo_list]  这种不行
            return [photo_obj.id for photo_obj in photo_list]
    
    只要有请求,就会报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
    
    原因是:无法将联表查询的图片格式的数据序列化,可以将其他utf-8格式的数据正常传输!具体的解决方法暂时没有找出!
    
    
    
    第二种:如上的serializer.py
    
    class Info_photomodelSerializer(serializers.ModelSerializer):
        class Meta:
            model = Info_photo
            fields = ['photo','id']
    
    class InformationModelSerializer(serializers.ModelSerializer):
        detail_photo = Info_photomodelSerializer(many=True)
        # 直接将表之间的关联字段拿过来作为一个序列化对象,考虑到时多条数据,因此可以将many设置为True 
       
        class Meta:
            model = Infomation
            fields = [ 'title',  'title_photo', 'create_time', 'id','detail_photo' ]
    这种正常传输所有的数据!
    备注:这种思路要序列化多个表,为什么不间接去拿到所需的数据呢?
    
    解决:利用django的双下划线去做!
  • 相关阅读:
    5.装饰器生成器迭代器
    python-进程&线程
    模块(二)
    MYSQL数据库操作(一)
    python-网络编程-socket编程
    python-异常处理
    python-面向对象进阶
    python-模块
    python_面向对象编程
    生成器 迭代器,装饰器 ,软件开发规范
  • 原文地址:https://www.cnblogs.com/changwenjun-666/p/11288821.html
Copyright © 2020-2023  润新知