Извлечение последнего экземпляра модели в modelSerializer другой модели в django rest framework

Я создаю rest API для веб-сайта, на котором пользователи могут приобрести одну из предоставляемых подписок.

На этом сайте есть API user-info, который возвращает информацию о вошедшем пользователе, которая может быть использована для отображения его информации на сайте. Проблема в том, что сериализатор упомянутого API является modelSerializer на модели "User", а информация, которую я хочу вернуть, является экземпляром модели "Subscription", на который ссылается последний экземпляр модели "SubPurchase"

Это мои сериализаторы, модели и представления. И мне нужно как-то вернуть ID и имя текущей подписки пользователя вместе с информацией о пользователе. Если у вас есть дополнительные вопросы, задавайте их в комментариях, и я отвечу на них.

# 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 дней после даты покупки

Если вас интересуют только возвращаемые данные, вы можете переопределить функцию 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


вы можете использовать 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')
Вернуться на верх