【问题标题】:How do I assign instances to models in django?如何将实例分配给 django 中的模型?
【发布时间】:2020-12-14 17:47:58
【问题描述】:

我正在构建一个儿童家务管理应用程序,但遇到了一个阻止程序。这是我正在尝试做的事情:

  • 为各个孩子分配各种规则的各个实例(即,有多个“洗碗”实例,这样一个孩子就可以完成他们的版本,而不会为每个孩子标记为完成),所以我将能够:
    • 仅在每个孩子的页面上显示分配给每个孩子的规则(即孩子 1 可以显示其规则 a、b、c 的实例,而孩子 2 可以显示其规则 b、c、d 的实例)
  • 最终目标是能够计算每个孩子获得的分数

这是我到目前为止所做的:

  • 显示所有孩子的列表
  • 能够创建规则实例
  • 显示每个孩子的所有规则实例。

这是我的模型:

class Rule(models.Model):
    """
    Model representing a base class for rules. Weight field is how much you want the rule to be worth. The same rule can be applied to multiple kids, and a single kid can be assigned multiple rules.
    """
    name = models.CharField(max_length=50, help_text='Enter rule', default=None)
    weight = models.IntegerField(default=0)
    description = models.TextField(max_length=250, help_text='Enter description of rule')
    completed = models.BooleanField(default=False, help_text='Is this rule completed?')

    def get_absolute_url(self):
        """
        url to gain access to one Rule
        """

        return reverse('rule-detail', args=[str(self.id)])

class RuleInstance(models.Model):
    """
    Model representing instances of rules. Instances should be assigned to kids.
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this rule')
    rule = models.ForeignKey(Rule, on_delete=models.SET_NULL, null=True)

class Kid(models.Model):

    name = models.CharField(max_length=20, help_text='Enter kid name', default=None)
    rules = models.ManyToManyField(RuleInstance, help_text='Select a rule to give to this kid')
    # https://docs.djangoproject.com/en/3.0/topics/db/examples/many_to_many/
    points = models.IntegerField(default=0)

    class Meta:
        ordering = ['name']

    # methods
    def __str__(self):
        return f'Name: {self.name}\n Points total: {self.points} \n Rules assigned: {self.rules}'

    def get_absolute_url(self):
        """
        url to gain access to one Kid
        """
    
        return reverse('kid-detail', args=[str(self.id)])

以下是相关观点:

def index(request):
    """
    view function for site homepage. Stuff below will be subject to change if I don't like how it looks
    """
    kids_list = Kid.objects.all()

    rules_list = Rule.objects.all()

    rule_instance_list = RuleInstance.objects.all()

    context = {
        'kids_list' : kids_list,
        'rules_list' : rules_list,
        'rule_instance_list': rule_instance_list,
    }

    return render(request, 'index.html', context=context)

class KidDetailView(generic.DetailView):
    model = Kid

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        context['rule_instance_list'] = RuleInstance.objects.all()

        return context

我应该如何调整我的模型或视图来完成我所追求的目标? Kid 和 RuleInstance 模型之间的多对多关系是解决这个问题的正确方法吗?

【问题讨论】:

    标签: python django django-models model instance


    【解决方案1】:
    • 由于每个 RuleInstance 只会分配给一个孩子,因此最好建立一对多的关系。
    • 由于规则的每个实例都应单独标记为“已完成”,因此 completed 字段应位于实例上,而不是规则上。

    像这样:

    class RuleInstance(models.Model):
        """
        Model representing instances of rules. Instances should be assigned to kids.
        """
        id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this rule')
        rule = models.ForeignKey(Rule, on_delete=models.SET_NULL, null=True)
        kid = models.ForeignKey(Kid, related_name='rules')
        completed = models.BooleanField(default=False, help_text='Is this rule completed?')
    

    这将为Kid 模型添加一个名为rules 的隐式字段。

    当您需要创建新的规则实例时,您将执行以下操作:

       RuleInstance.objects.create(rule=the_rule, kid=the_kid)
    

    (如果家务很正常,您可能还需要 RuleInstance 上的“日期”字段。)

    【讨论】:

    • 这让模型的行为完全符合我的要求。谢谢!
    • 不用担心。如果您觉得答案有用,您介意点赞和/或接受吗?
    猜你喜欢
    • 2021-10-02
    • 2015-01-28
    • 2012-05-26
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多