【问题标题】:Multi-level access with ManyToMany relationships in Django在 Django 中使用多对多关系进行多级访问
【发布时间】:2022-01-09 06:33:40
【问题描述】:

我有模型,对象可以表示为有向图:

from django.db import models
from django.contrib.auth.models import User

class Record(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=500)
    content = models.TextField()
    sequels = models.ManyToManyField('self', blank=True, symmetrical=False, through='Extend', related_name='extending')
    author = models.ForeignKey(User, on_delete=models.CASCADE)

class Extend(models.Model):
    ancestor = models.ForeignKey(Record, on_delete=models.CASCADE, related_name='+')
    descendant = models.ForeignKey(Record, on_delete=models.CASCADE, related_name='+')

    class Meta:
        constraints = [
            models.UniqueConstraint(
                name="%(app_label)s_%(class)s_unique_relationships",
                fields=["ancestor", "descendant"],
            ),
            models.CheckConstraint(
                name="%(app_label)s_%(class)s_prevent_self_extend",
                check=~models.Q(ancestor=models.F("descendant")),
            ),
        ]

任何时候创建Record 的新实例并且它通过Extend 模型与另一个实例有关系,我很想在User 实例中计算author.user.userprofile.income 属性。问题是我不知道如何为新创建的Record 的所有祖先计算这个属性,它遵循一些规则:如果新创建的Record 成本为 50,则第一级祖先获得 ​​25 和 25 去其他祖先,不断被2除。

一级祖宗的公式我可以写,别人怎么写?

# In case of some purchase:
class ExtendPurchase(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    items = models.ManyToManyField(Record)
    date = models.DateField(auto_now_add=True)
    cost = models.PositiveIntegerField()

    def calculate_income(self):
        for item in self.items.all():
            item.author.userprofile.income += self.cost / len(self.items.all()) / 2 # first-level; if one would like to extend more than one Record instance
            for ancestor in item.extending.all():
                ancestor.author.userprofile.income += self.cost / delimiter # I don't know what delimiter is to be written
        self.items.save()

【问题讨论】:

标签: django django-models many-to-many


【解决方案1】:

如果我理解正确,您希望递归地遍历记录,然后将每个循环中的成本除以 2。

这对你有用吗?

class ExtendPurchase(models.Model):
    # ...

    def calculate_income(self):

        def __income_from_record(record, cost):
            tmp_income = cost
            for rel in Extend.objects.select_related('descendant').filter(ancestor=record):
                tmp_income += __income_from_record(rel.descendant, cost/2)
            return tmp_income

        for record in self.items.all():
            income = __income_from_record(record, self.cost)
            record.ancestor.author.userprofile.income  = income
            record.ancestor.author.userprofile.save()

【讨论】:

  • Record 对象没有属性ancestor。虽然我可以使用for ancestor in record.extending.all() 访问所有祖先
  • @PavelShlepnev,可以是`record.author.userprofile。
猜你喜欢
  • 1970-01-01
  • 2012-04-30
  • 2015-07-09
  • 1970-01-01
  • 2019-07-01
  • 2011-02-27
  • 2013-11-24
  • 2020-02-04
  • 2021-06-24
相关资源
最近更新 更多