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的双下划线去做!

 

posted on 2019-08-02 15:30  michael-chang  阅读(659)  评论(0编辑  收藏  举报

导航