Tôi hiểu cách chia nhỏ mô hình và tôi hiểu lý do phụ thuộc vào mô-đun vòng tròn làm tăng mọi thứ, nhưng tôi đã gặp phải sự cố khi chia nhỏ mô hình thành các tệp riêng biệt dường như gây ra phụ thuộc vòng tròn. Dưới đây là một exerpt từ mã, và tôi sẽ làm theo nó với traceback từ quá trình thất bại:Phụ thuộc mô-đun tròn trong Python/Django với các mô hình chia tách
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)
Từ những gì tôi có thể thấy, không có đệ quy tròn rõ ràng ông lại, lưu các tài liệu tham khảo cần thiết trong __init__.py
mà dường như là nơi mọi thứ được thổi lên trong mã của tôi. Dưới đây là traceback:
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, in <module>
from competency.models import CompetencyProduct
File "/path/to/project/django/myproj/competency/models.py", line 5, in <module>
from ecom.models import Product
File "/path/to/project/django/myproj/ecom/models/__init__.py", line 5, in <module>
from ecom.models.permissions import Permission
File "/path/to/project/django/myproj/ecom/models/permissions.py", line 8, in <module>
from course.models import Course
File "/path/to/project/django/myproj/course/models.py", line 4, in <module>
from competency.models import CompetencyProduct
ImportError: cannot import name CompetencyProduct
Tất cả tôi đang cố gắng để làm ở đây là nhập khẩu mà Elearning
mô hình, mà là một lớp con của CompetencyProduct
, và đến lượt nó, Product
. Tuy nhiên, vì Product
xuất phát từ sự bùng nổ của ecom/models.py
lớn hơn, tệp ecom/__init__.py
chứa nhập khẩu bắt buộc của tất cả các mô hình bị hỏng, bao gồm Permission
phải nhập Course
yêu cầu CompetencyProduct
.
Điều kỳ quặc là toàn bộ trang web hoạt động tốt. Đăng nhập, mua hàng, mọi thứ. Vấn đề này chỉ xảy ra khi tôi đang cố gắng chạy cần tây trong nền và một nhiệm vụ mới được tải hoặc tôi cố gắng chạy một kịch bản shell bằng cách sử dụng môi trường Django.
Là lựa chọn duy nhất của tôi ở đây để xóa Permission
khỏi ứng dụng ecom
hoặc có cách nào tốt hơn, thông minh hơn để xử lý việc này? Ngoài ra, bất kỳ ý kiến về cách tôi đã đặt ra các dự án nói chung được đánh giá cao.
Tại sao phải đưa ra một ví dụ đơn giản rằng * không * minh họa sự cố? Bạn đúng; không có phụ thuộc vòng tròn ở đó, nhưng có * là * trong mã thực tế của bạn. Gửi mã thực tế cho bạn, bạn có thể chỉnh sửa bất kỳ thứ gì không áp dụng, nhưng sẽ giúp bạn xem các tệp và mô hình thực tế của bạn được đặt ra như thế nào trong dự án của bạn. –
Bạn nói đúng. Tôi đã thay đổi nó ngay bây giờ. –