django DRF:尝试使用SlugRelatedField和slug_field中的双下划线创建示例时出现AttributeError

bkhjykvo  于 2023-03-31  发布在  Go
关注(0)|答案(1)|浏览(82)

当示例成功创建并保存在数据库中时,我收到此错误,并使用POST请求和DRF:

AttributeError: 'UserProfile' object has no attribute 'user__username'

下面是我的UserProfile和**UserImpression”模型:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE, primary_key=True)
    avatar = models.ImageField(upload_to=user_directory_path, null=True, blank=True)
    imp_laptop = models.ManyToManyField(Laptop, related_name="laptop_impression", through="UserImpression", through_fields=('profile', 'laptop'))

    objects = models.Manager()
    custom_manager = UserProfileCustomManager()

    def __str__(self):
        return self.user.username + ' profile'

class UserImpression(models.Model):
    profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
    laptop = models.ForeignKey(Laptop, on_delete=models.CASCADE)
    liked = models.BooleanField(default=True)

    class Meta:
        constraints = [
          models.UniqueConstraint(fields=['profile', 'laptop'], name='unique_profile_laptop_impression'),
        ]

我的序列化程序类UserImpressionSerializer

class UserImpressionSerializer(serializers.ModelSerializer):
    profile = serializers.SlugRelatedField(queryset=UserProfile.objects.all(), slug_field="user__username")
    laptop = serializers.SlugRelatedField(queryset=Laptop.objects.all(), slug_field="slug")

    class Meta:
        model = UserImpression
        fields = ['profile', 'laptop', 'liked']
        validators = [
          UniqueTogetherValidator(
              queryset=UserImpression.objects.all(),
              fields=['profile', 'laptop']
          )
        ]

    def create(self, validated_data):
      
      profile = validated_data.get("profile", None)
      laptop = validated_data.get("laptop", None)

      if profile is None:
        raise serializers.ValidationError(
          {"profile": "Cannot retrieve the profile instance with the username"}
        )
      if laptop is None:
        raise serializers.ValidationError(
          {"laptop": "Cannot retrieve the laptop instance with the laptop slug"}
        )
      liked = validated_data.get("liked", True)
      return UserImpression.objects.create(profile=profile, laptop=laptop, liked=liked)

在我看来

class UserLikeDislike(generics.CreateAPIView, generics.UpdateAPIView, generics.DestroyAPIView):
    permission_classes = [IsAuthenticated, TokenHasReadWriteScope]
    queryset = UserImpression.objects.all()
    serializer_class = UserImpressionSerializer

我设置profile字段的目的是通过User模型中的username字段获取UserProfile示例,User模型和UserProfile模型是一一对应的关系。
任何帮助或建议将不胜感激!任何其他方向,以达到我的目标也将是伟大的以及!

1mrurvl1

1mrurvl11#

正如你在问题中提到:
使用POST请求和DRF成功创建示例并将其保存在数据库中
这意味着保存工作正常,但GET请求失败。这是因为SlugRelatedField试图通过slug_field(源)直接使用getattr获取数据。这将导致错误,因为UserImpression对象没有名为user__username的字段。
因此,我建议重写RelatedField的to_represenation函数,如下所示:

class CustomField(serializers.SlugRelatedField):
    def to_representation(self, value):
        return value.user.username

class UserImpressionSerializer(serializers.ModelSerializer):
    profile = CustomField(queryset=UserProfile.objects.all(), slug_field="user__username")

相关问题