【问题标题】:Serializing joined tables in serializers rest framework在序列化程序休息框架中序列化连接表
【发布时间】:2018-09-13 23:58:00
【问题描述】:

所以我正在尝试使用 django 序列化程序序列化多个连接表。我找不到办法做到这一点。正在执行的查询是原始 sql。 型号如下

class UserDetail(models.Model):
    user = models.OneToOneField(User, on_delete = models.CASCADE)
    mobile_number = models.IntegerField()
    national_id = models.CharField(max_length = 30)
    date_created = models.DateTimeField(auto_now_add = True)
    address = models.CharField(max_length = 250)
    merchant_name = models.CharField(null = True, max_length = 30)

class Account(models.Model):
    user = models.OneToOneField(User, on_delete = models.CASCADE)
    account_number = models.BigIntegerField()
    balance = models.FloatField()
    account_type = models.ForeignKey(AccountType, on_delete = models.CASCADE)

预期结果的json应该如下

{
  "userdetail": {
                 "mobile_number":""
              },
  "account": {
              "account_number":""
          },
  "user": {
  "first_name": "",
  "last_name": "",
  "email":""
      }
  }

原始的sql查询如下

queryset = Account.objects.raw('''SELECT auth_user.first_name,
                                                 auth_user.id,
                                                 auth_user.last_name,
                                                 auth_user.email,
                                                 authentication_userdetail.mobile_number,
                                                 authentication_account.account_number
                                           FROM
                                                 public.auth_user,
                                                 public.authentication_account,
                                                 public.authentication_userdetail
                                           WHERE
                                                 auth_user.id = authentication_userdetail.user_id
                                           AND
                                                 auth_user.id = authentication_account.user_id
                                        ''')

如果有不使用原始 sql 的替代方法,我将不胜感激,因为我不喜欢使用 django ORM 执行原始 sql 查询

尝试使用此解决方案,但我似乎无法理解查询集的序列化方式 Cross-table serialization Django REST Framework

已编辑

class UserDetailSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserDetail
        fields = ('mobile_number',)

class AccountSerializer(serializers.ModelSerializer):

    class Meta:
        model = Account
        fields = ('account_number',)


class AccountInfoSerializer(serializers.ModelSerializer):
    user_detail = UserDetailSerializer()
    account = AccountSerializer()
    user = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ('user_detail', 'account', 'user')
    def get_user(self, obj):
        return {
            'first_name': 'obj.first_name',
            'last_name': 'obj.last_name',
            'email': 'obj.email',
           }

视图代码

serializer_class = AccountInfoSerializer

def get_queryset(self, *args, ** kwargs):
    user_id = self.request.query_params.get('user_id', None)
    queryset = None
    if user_id is not '':
        queryset = UserDetail.objects.raw()
    return queryset

【问题讨论】:

    标签: django django-rest-framework django-orm


    【解决方案1】:

    你可以试试这样的解决方案:

    from rest_framework import serializers
    
    class UserDetailSerializer(serializers.ModelSerializer):
        class Meta:
            model = UserDetail
            fields = ('mobile_number',)
    
    
    class AccountSerializer(serializers.ModelSerializer):
        class Meta:
            model = Account
            fields = ('account_number',)
    
    
    class UserSerializer(serializers.ModelSerializer):
        userdetail = UserDetailSerializer()
        account = AccountSerializer()
        user = serializers.SerializerMethodField()
    
        class Meta:
            model = User
            fields = ('userdetail', 'account', 'user')
    
        def get_user(self, obj):
            return {
                'first_name': 'obj.first_name',
                'last_name': 'obj.last_name',
                'email': 'obj.email',
                }
    

    【讨论】:

    • 在序列化器 UserSerializer. The serializer field might be named incorrectly and not match any attribute or key on the UserDetail` 实例上尝试获取字段 user_detail 的值时返回 AttributeError
    • class AccountInfoSerializer(serializers.ModelSerializer): user_detail = UserDetailSerializer() account = AccountSerializer() user = serializers.SerializerMethodField() class Meta: model = User fields = ('user_detail', 'account', 'user') def get_user(self, obj): return { 'first_name': 'obj.first_name', 'last_name': 'obj.last_name', 'email': 'obj.email', }
    • 不需要序列化器的代码,怎么调用的,例如instance = User.objects.last(); serializer = AccountInfoSerializer(instance)
    • AccountInfoSerializer 具有元模型 User 但在 queryset 您将查询返回到 UserDetail 将其更改为 User
    • 感谢它的工作。修复了您突出显示的位置,还发现字段名称与 UserDetail 的模型名称不同
    猜你喜欢
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2021-04-08
    • 2016-07-19
    相关资源
    最近更新 更多