【问题标题】:retrieving the last instance of a model in another model's modelSerializer in django rest framework在django rest框架中检索另一个模型的modelSerializer中模型的最后一个实例
【发布时间】:2022-01-30 23:03:39
【问题描述】:

我正在为一个网站创建 REST API,用户可以在其中购买所提供的订阅之一。

在这个网站上有一个用户信息 API,它返回有关登录用户的信息,可用于在网站上显示他们的信息。 问题是,上面提到的 API 的序列化器是“用户”模型上的模型序列化器,而我要返回的信息是“订阅”模型的最新实例所引用的“订阅”模型的实例。

这些是我的序列化程序、模型和视图。我需要以某种方式返回用户当前订阅的 ID 和名称以及用户信息。如果您还有任何问题,请在 cmets 中问我,我会回答。

# models.py
class User(AbstractBaseUser, PermissionsMixin):
    userID = models.AutoField(primary_key=True)
    username = models.CharField(max_length=100, unique=True, validators=[RegexValidator(regex="^(?=[a-z0-9._]{5,20}$)(?!.*[_.]{2})[^_.].*[^_.]$")])
    email= models.EmailField(max_length=100, unique=True,  validators=[EmailValidator()])
    name = models.CharField(max_length=100)
    isSuspended = models.BooleanField(default=False)
    isAdmin = models.BooleanField(default=False)
    emailActivation = models.BooleanField(default=False)
    balance = models.IntegerField(default=0)

    objects = UserManager()

    USERNAME_FIELD = 'username'


class Subscription(models.Model):
    subID = models.AutoField(primary_key=True)
    nameOf = models.CharField(max_length=50)
    price = models.PositiveIntegerField()
    salePercentage = models.PositiveIntegerField(default=0)
    saleExpiration = models.DateTimeField(default=datetime.datetime.now, blank=True)

    def __str__(self):
        return f"{self.nameOf}"


class SubPurchase(models.Model):
    price = models.PositiveIntegerField()
    dateOf = models.DateTimeField(auto_now_add=True)
    
    user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    subscription = models.ForeignKey(Subscription, null=True, on_delete=models.SET_NULL)
    
    def __str__(self):
        return self.subscription
# serializers.py
class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = get_user_model()
        fields = ('userID', 'username','email', 'name', 'balance', 'emailActivation', 'isSuspended')
        read_only_fields = ('userID', 'username','email', 'name', 'balance', 'emailActivation', 'isSuspended')


# views.py
class UserInfoViewSet(viewsets.ModelViewSet):
    queryset = get_user_model().objects.all()
    serializer_class = UserInfoSerializer

    def get_queryset(self):
        uID = getattr(self.request.user,'userID')
        return get_user_model().objects.filter(userID=uID)

    def get_object(self):
        uID = getattr(self.request.user,'userID')
        return self.queryset.filter(userID=uID)

再次,我需要更改 UserInfoSerializer,以提供用户当前订阅的名称、ID 和到期日期,即购买日期后 30 天

【问题讨论】:

    标签: django django-models django-rest-framework django-serializer


    【解决方案1】:

    如果你只对返回的数据感兴趣,你可以重写你的序列化器的函数to_representation,并为你的相关模型创建一个序列化器。如果我理解正确,您用户的当前订阅是最后一个(如果按“dateOf”排序)。所以这样的事情可以解决问题

    class SubscriptionSerializer(serializers.ModelSerializer):
         class Meta:
               model = Subscription
               fields = ('nameOf', 'id', 'saleExpiration ')
    
    class UserInfoSerializer(serializers.ModelSerializer):
        class Meta:
            model = get_user_model()
            fields = ('userID', 'username','email', 'name', 'balance', 'emailActivation', 'isSuspended')
            read_only_fields = ('userID', 'username','email', 'name', 'balance', 'emailActivation', 'isSuspended')
    
        def to_representation(self, instance):
             data = super().to_representation(instance)
             current_subs = instance.subpurchase_set.order_by('dateOf').last().subscription
             data['current_subscription'] = SubscriptionSerializer(instance=current_subs).data
             return data
    
    
    

    【讨论】:

    • 我要找的失效日期不是这个,但这帮助我得到了正确的答案。所以谢谢。
    【解决方案2】:

    您可以使用NestedSerializers 来实现您正在寻找的东西

    基本上,嵌套序列化是一种方法,您可以在其中从另一个模型返回、创建、放入......到一个模型中,它是这样的......

    models.py

    class User(AbstractBaseUser, PermissionsMixin):
    ....
    #user model data
    
    class SubPurchase(models.Model):
       ...
      user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
    

    serializers.py

    class SubscriptionSerializer(serializers.ModelSerializer):
         class Meta:
             model = Subscription
             fields =["anyfield you wanna include"]
    
    class SubPurchaseSerializer(serializers.ModelSerializer):
         class Meta:
             model = SubPurchase
             fields =["anyfield you wanna include"]
    
    
    class UserInfoSerializer(serializers.ModelSerializer): 
           subpurchace = SubPurchaseSerializer()
           subscription= SubscriptionSerializer() #later included in the fields of this serializer
        class Meta:
            model = get_user_model()
            fields = ('userID','subpurchace', 'subscription', 'username','email', 'name', 'balance', 'emailActivation', 'isSuspended')
            read_only_fields = ('userID', 'username','email', 'name', 'balance', 'emailActivation', 'isSuspended')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-02
      • 1970-01-01
      • 2015-02-27
      • 2016-05-30
      • 1970-01-01
      • 2012-08-05
      • 2023-03-23
      • 2019-08-01
      相关资源
      最近更新 更多