-1

在以下模型中...

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    likes = models.IntegerField(default=0)
    dislikes = models.IntegerField(default=0)
    pub_at = models.DateTimeField(auto_now_add=True)
    category = models.ForeignKey(
        Category, on_delete=models.SET_NULL, null=True)

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

    def validity(self):
        total_likes = self.likes + self.dislikes

        if total_likes != 0:
            return (self.likes / total_likes) * 100
        else:
            return 100

Question.objects.get(pk=1).validity()假设pk=1在这种情况下存在,我希望能够访问。在 python shell 中,我可以很容易地做到这一点。但是我如何使用 React 来做到这一点。我能够毫无问题地获得我所有的问题和 React 中的字段,但我认为我没有办法访问validity我创建的方法。

4

3 回答 3

1

您可能希望使用@property装饰器,以便您可以像访问 Question 模型上的任何其他字段一样访问该值:

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    likes = models.IntegerField(default=0)
    dislikes = models.IntegerField(default=0)
    pub_at = models.DateTimeField(auto_now_add=True)
    category = models.ForeignKey(
        Category, on_delete=models.SET_NULL, null=True)

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

    @property
    def validity(self):
        total_likes = self.likes + self.dislikes
        percentage = (self.likes / total_likes) * 100
        return percentage

可以在文档此处找到说明。请记住,当您运行迁移时,它不会像其他属性一样保存为数据库中的列。

于 2020-09-10T23:59:26.480 回答
1

在这种情况下,我会建议以下内容。首先,从模型中删除属性:

# models.py

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    likes = models.IntegerField(default=0)
    dislikes = models.IntegerField(default=0)
    pub_at = models.DateTimeField(auto_now_add=True)
    category = models.ForeignKey(
        Category, on_delete=models.SET_NULL, null=True)

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

然后将SerializerMethodField( docs ) 添加到您的序列化程序中。它是只读的,可用于将计算值传递给您的视图:

# serializers.py

class QuestionSerializer(serializers.ModelSerializer):
    validity = serializers.SerializerMethodField()

    class Meta:
        model = Question
        fields = ['question_text', 'likes', 'dislikes', 'pub_at', 'category', 'validity']

    def get_validity(self, instance):
        total_likes = instance.likes + instance.dislikes
        # Your approach is not wrong. This is a more explicit way of dealing with that particular error type
        try:
            return (instance.likes / total_likes) * 100
        except ZeroDivisionError:
            return 100

请记住,category在这种情况下,外键将被序列化为其数据库唯一 id 值(主键)。

于 2020-09-11T11:37:04.550 回答
0

我在这里回答我自己的问题,我找到了解决方案。虽然,@property在使用 React 时使用简单的 Django 模板进行渲染并且渲染 json 响应validity仍然不可用时,它确实有效。

在我的 serializers.py 文件中,我执行了以下操作...

class QuestionSerializer(serializers.ModelSerializer):
    validity = serializers.ReadOnlyField()

    class Meta:
        model = Question
        fields = '__all__'

从模型中删除 @property,因为它不再需要。这对我有用,你可以去 Django rest_framework 或在你的 React 应用程序中测试它,看看你是否可以访问它。

我想知道这样做是否有任何问题和/或更好的方法。我也试图做validity = serializers.Field()而不是validity = serializers.ReadOnlyField()但得到一个错误说我需要一个Field.to_representation()作为self, value位置参数的。

我在这里传递的究竟是什么论点。我试过self, Question.validity了,但没有奏效。我不确定我在这里做什么。

作为更新模型中的方法,我更新为...

def validity(self):
        total_likes = self.likes + self.dislikes

        if total_likes != 0:
            return (self.likes / total_likes) * 100
        else:
            return 100

我以前没有注意到,对于这个问题并不重要,但除以零是不允许的,因为默认情况下除以零总是会发生。

于 2020-09-11T07:02:36.053 回答