Django,如何将基本模型转换为代理模型

huangapple go评论57阅读模式
英文:

Django, how to cast base model to proxy model

问题

我在代码中有一个地方,需要重载模型的属性。为此,我正在使用我的基础实例的代理模型。

模型:

class Question(TimeTrack):
    class Types(models.TextChoices):
        SINGLE_CHOICE = "SC", _("单选题")
        MANY_CHOICE = "MC", _("多选题")
        TRUE_FALSE = "TF", _("判断题")
        CHRONOLOGY = "CHR", _("时序题")
        MATCHING = "MCH", _("匹配题")

    position = models.PositiveIntegerField()
    text = models.CharField(max_length=512)
    image_src = models.CharField(max_length=256, blank=True, null=True)
    time = models.PositiveIntegerField()
    feedback = models.CharField(max_length=512)
    type = models.CharField(max_length=30, choices=Types.choices)
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)

    @property
    def answers(self):
        return self.answer_set.all()

    @property
    def correct_answers(self):
        return self.answer_set.filter(is_correct=True)

    def __str__(self):
        return f"问题 #{self.id}"

class ShuffledQuestion(Question):
    class Meta:
        proxy = True
    
    @property
    def answers(self):
        _answers = list(super().answers)
        random.shuffle(_answers)
        return _answers

以及我创建代理的地方:

_question_data = model_to_dict(question)
_question_data["quiz"] = question.quiz
_question_data["group"] = question.group
newQuestion = ShuffledQuestion(**_question_data)

上述方法可以正常工作,但我想知道是否有更"优雅"的方法来实现相同的功能。

英文:

I have a place in my code, where I need to overload model's property. For this matter I'm using proxy model of my base instance.

models:

class Question(TimeTrack):
    class Types(models.TextChoices):
        SINGLE_CHOICE = "SC", _("single_choice")
        MANY_CHOICE = "MC", _("many_choice")
        TRUE_FALSE = "TF", _("true_false")
        CHRONOLOGY = "CHR", _("chronology")
        MATCHING = "MCH", _("matching")

    position = models.PositiveIntegerField()
    text = models.CharField(max_length=512)
    image_src = models.CharField(max_length=256, blank=True, null=True)
    time = models.PositiveIntegerField()
    feedback = models.CharField(max_length=512)
    type = models.CharField(max_length=30, choices=Types.choices)
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)

    @property
    def answers(self):
        return self.answer_set.all()

    @property
    def correct_answers(self):
        return self.answer_set.filter(is_correct=True)

    def __str__(self):
        return f"Question #{self.id}"

class ShuffledQuestion(Question):
    class Meta:
        proxy = True
    
    @property
    def answers(self):
        _answers = list(super().answers)
        random.shuffle(_answers)
        return _answers

and the place where I create proxy:

_question_data = model_to_dict(question)
_question_data["quiz"] = question.quiz
_question_data["group"] = question.group
newQuestion = ShuffledQuestion(**_question_data)

The above works just fine, but I wonder if there is "more elegant" way to accomplish the same.

答案1

得分: 0

你不需要真正将模型数据转换为它的代理模型,因为代理模型与原始模型具有相同的数据,毕竟它们共享数据库中的相同表。

要将模型“转换”为其代理模型,你可以在代理模型查询集上使用 get 方法:

ShuufledQuestion.objects.get(pk=question.pk)

这将具有与原始模型相同的数据,但具有不同的Django方法/属性/管理器等。

英文:

You don't really cast model data into it's proxy model, because proxy model has same data as original model, they share same table in DB after all.

To "cast" model into it's proxy you can use get method on proxy model queryset:

ShuufledQuestion.objects.get(pk=question.pk)

And it will have same data as original model, but different Django methods/properties/managers etc.

huangapple
  • 本文由 发表于 2023年2月23日 20:29:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75544853.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定