【问题标题】:django circular import in models模型中的 django 循环导入
【发布时间】:2021-04-06 11:43:04
【问题描述】:

我知道我在这里有一个循环导入,但其中一个用于定义一些外键字段,另一个仅用于另一个模型中的属性。

型号:

收据/models.py

from django.db import models
from employees.models import Employee

class Receipt(models.Model):
    Supervisor = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='receipt_supervisor')
    Employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='receipt_employee')
    amount = models.DecimalField(max_digits=6, decimal_places=2)

员工/models.py

from django.db import models
from receipts.models import Receipt

class Employee(models.Model):
    number = models.CharField(max_length=50, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

    @property
    def receipt_sum(self):
        receipts = Receipt.objects.filter(Employee=self.pk)
        sum = 0
        for receipt in receipts:
            sum += receipt.amount
        return sum

我收到此错误:

无法从部分初始化的模块“employees.models”导入名称“Employee”(很可能是由于循环导入)

有没有办法解决这个问题,以便我可以在 Employee 属性中进行收据查询?还是我需要在别处进行此计算?

谢谢!

【问题讨论】:

  • 尝试在 employee.models.pydef receipt_sum(self): 中导入 Receipt,例如 def receipt_sum(self): from receipts.models import Receipt ....
  • 嗨丹尼尔,你有没有试过在这里搜索类似的问题?看看这个答案,我相信它回答了你的问题:*.com/a/4379094/4744341

标签: python django importerror


【解决方案1】:

有没有办法解决这个问题,以便我可以在 Employee 属性中进行收据查询?

可以,可以在方法中导入模块:

from django.db import models

class Employee(models.Model):
    number = models.CharField(max_length=50, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

    @property
    def receipt_sum(self):
        from receipts.models import Receipt
        receipts = Receipt.objects.filter(Employee=self.pk)
        sum = 0
        for receipt in receipts:
            sum += receipt.amount
        return sum

但其实根本不需要导入Receipt,可以利用receipt_employee关系来访问相关的Receipt对象,也可以用.aggregate(…) [Django-doc]来总结数据库方面,这可能更有效:

from django.db import models
from django.db.models import Sum

class Employee(models.Model):
    number = models.CharField(max_length=50, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

    @property
    def receipt_sum(self):
        return self.receipt_employee.aggregate(
            total=Sum('amount')
        )['total'] or 0

【讨论】:

  • 哦!甜的!导入属性是要走的路。我有一些额外的数学和过滤,我认为会混淆这个问题,但先生给你加分!
  • 我只是意识到关系可以应用过滤器方法receipts = self.receipt_employee.filter(is_deleted=False, created_at__year=datetime.now().year)这真的是我想要的!再次感谢@WillemVanOnsem