我理解如何分解模型,我理解为什么循环模块依赖性会搞砸,但我遇到了一个问题,即将模型分解为单独的文件似乎会导致循环依赖.这是代码中的一个exerpt,我将跟踪失败过程中的回溯:
elearning/tasks.py
from celery.task import task @task def decompress(pk): from elearning.models import Elearning Elearning.objects.get(pk=pk).decompress()
elearning/models.py
from competency.models import CompetencyProduct from core.helpers import ugc_elearning from elearning.fields import ArchiveFileField class Elearning(CompetencyProduct): archive = ArchiveFileField(upload_to=ugc_elearning) def decompress(self): import zipfile src = self.archive.path dst = src.replace(".zip","") print "Decompressing %s to %s" % (src, dst) zipfile.ZipFile(src).extractall(dst)
ecom/models/products.py
from django.db import models from django.utils.translation import ugettext_lazy as _ from core.models import Slugable, Unique from django_factory.models import Factory from core.helpers import ugc_photos class Product(Slugable, Unique, Factory): photo = models.ImageField(upload_to=ugc_photos, width_field="photo_width", height_field="photo_height", blank=True) photo_width = models.PositiveIntegerField(blank=True, null=True, default=0) photo_height = models.PositiveIntegerField(blank=True, null=True, default=0) description = models.TextField() price = models.DecimalField(max_digits=16, decimal_places=2) created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True)
ecom/models/__init__.py
from django.contrib.auth.models import User from django.db import models from ecom.models.products import Product, Credit, Subscription from ecom.models.permissions import Permission from ecom.models.transactions import Transaction, DebitTransaction, CreditTransaction, AwardTransaction, FinancialTransaction, PermissionTransaction, BundleTransaction
competency/models.py
from django.db import models from django.utils.translation import ugettext_lazy as _ from core.models import Slugable, Unique from ecom.models import Product from rating.models import Rated from trainer.models import Trainer class Competency(Slugable, Unique): class Meta: verbose_name = _("Competency") verbose_name_plural = _("Competencies") description = models.TextField() class CompetencyProduct(Product, Rated): class Meta: verbose_name = _("Product") verbose_name_plural = _("Products") release = models.DateField(auto_now_add=True) trainers = models.ManyToManyField(Trainer) competencies = models.ManyToManyField(Competency, related_name="provided_by") requirements = models.ManyToManyField(Competency, related_name="required_for", blank=True, null=True) forsale = models.BooleanField("For Sale", default=True)
ecom/models/permissions.py
from django.contrib.auth.models import User from django.db import models from django.utils.translation import ugettext_lazy as _ from treebeard.mp_tree import MP_Node from collective.models import Collective from course.models import Course from ecom.models.products import Product class Permission(MP_Node): class Meta: app_label = "ecom" product = models.ForeignKey(Product, related_name="permissions") user = models.ForeignKey(User, related_name="permissions") collective = models.ForeignKey(Collective, null=True) course = models.ForeignKey(Course, null=True) redistribute = models.BooleanField(default=False) created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) accessed = models.DateTimeField(auto_now=True)
course/models.py
from django.db import models from django.utils.translation import ugettext_lazy as _ from competency.models import CompetencyProduct from ecom.models import Product from rating.models import Rated class Chapter(models.Model): seq = models.PositiveIntegerField(name="Sequence", help_text="Chapter number") name = models.CharField(max_length=128) note = models.CharField(max_length=128) class Course(Product, Rated): level = models.PositiveIntegerField(choices=CompetencyProduct.LEVELS) chapters = models.ManyToManyField(Chapter) class Bundle(models.Model): class Meta: unique_together = (("product", "chapter"),) product = models.ForeignKey(Product, related_name="bundles") chapter = models.ForeignKey(Chapter, related_name="bundles") amount = models.PositiveIntegerField() seq = models.PositiveIntegerField(name="Sequence", default=1)
从我所看到的,这里没有明确的循环递归,除了所需的引用,__init__.py
其中似乎是我的代码中的事情正在爆炸.这是追溯:
File "/path/to/project/virtualenv/lib/python2.6/site-packages/celery/execute/trace.py", line 47, in trace return cls(states.SUCCESS, retval=fun(*args, **kwargs)) File "/path/to/project/virtualenv/lib/python2.6/site-packages/celery/app/task/__init__.py", line 247, in __call__ return self.run(*args, **kwargs) File "/path/to/project/virtualenv/lib/python2.6/site-packages/celery/app/__init__.py", line 175, in run return fun(*args, **kwargs) File "/path/to/project/django/myproj/elearning/tasks.py", line 5, in decompress from elearning.models import Elearning File "/path/to/project/django/myproj/elearning/models.py", line 2, infrom competency.models import CompetencyProduct File "/path/to/project/django/myproj/competency/models.py", line 5, in from ecom.models import Product File "/path/to/project/django/myproj/ecom/models/__init__.py", line 5, in from ecom.models.permissions import Permission File "/path/to/project/django/myproj/ecom/models/permissions.py", line 8, in from course.models import Course File "/path/to/project/django/myproj/course/models.py", line 4, in from competency.models import CompetencyProduct ImportError: cannot import name CompetencyProduct
我在这里尝试做的就是导入该Elearning
模型,这是一个子类CompetencyProduct
,反过来Product
.然而,由于Product
来自于大的破裂ecom/models.py
,该ecom/__init__.py
文件包含了所有断开的车型的强制性进口,包括Permission
其中有进口Course
需要CompetencyProduct
.
古怪的是,整个网站完美地运作.登录,购买,一切.这个问题只发生在我尝试在后台运行芹菜并加载新任务或我尝试使用Django环境运行shell脚本时.
我是唯一可以Permission
从ecom
应用程序中删除的选项,还是有更好,更智能的方法来处理这个问题?此外,对我如何布置项目的任何评论都表示赞赏.