2017-07-25 102 views
0

在使用我的Django项目运行makemigrations/migrate时遇到问题。Django中的循环依赖错误

收到此错误:

Traceback (most recent call last): 
    File "manage.py", line 10, in <module> 
    execute_from_command_line(sys.argv) 
    File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\__init__.py", line 353, in execute_from_command_line 
    utility.execute() 
    File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\__init__.py", line 345, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\base.py", line 348, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\base.py", line 399, in execute 
    output = self.handle(*args, **options) 
    File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\commands\migrate.py", line 139, in handle 
    plan = executor.migration_plan(targets) 
    File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\migrations\executor.py", line 60, in migration_plan 
    for migration in self.loader.graph.forwards_plan(target): 
    File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\migrations\graph.py", line 149, in forwards_plan 
    self.ensure_not_cyclic(target, lambda x: (parent.key for parent in self.node_map[x].parents)) 
    File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\migrations\graph.py", line 241, in ensure_not_cyclic 
    raise CircularDependencyError(", ".join("%s.%s" % n for n in cycle)) 
django.db.migrations.exceptions.CircularDependencyError: accounts.0001_initial, projects.0001_initial 

我有两个应用程序---一个叫帐户和另一个名为项目

我的帐户的应用程序,这里是模型:

from django.contrib.auth.models import (
    AbstractBaseUser, 
    BaseUserManager, 
    PermissionsMixin 
) 
from django.db import models 
from django.utils import timezone 
from django.conf import settings 
from django.db.models.signals import post_save 
import os 

from projects.models import Skill, Project 


def avatar_upload_path(instance, filename): 
    return os.path.join('avatars', 'user_{0}', '{1}').format(
     instance.user.id, filename) 

class UserManager(BaseUserManager): 
    def create_user(self, email, username=None, password=None): 
     if not email: 
      raise ValueError("Users must have an email address") 

     if not username: 
      username = email.split('@')[0] 

     user = self.model(
      email=self.normalize_email(email), 
      username=username, 
     ) 
     user.set_password(password) 
     user.save() 
     return user 

    def create_superuser(self, email, username, password): 
     user = self.create_user(
      email, 
      username, 
      password, 
     ) 
     user.is_staff = True 
     user.is_superuser = True 
     user.save() 
     return user 


class User(AbstractBaseUser, PermissionsMixin): 
    email = models.EmailField(unique=True) 
    username = models.CharField(max_length=40, unique=True, default='') 
    date_joined = models.DateTimeField(default=timezone.now) 
    is_active = models.BooleanField(default=True) 
    is_staff = models.BooleanField(default=False) 

    objects = UserManager() 

    USERNAME_FIELD = 'email' 
    REQUIRED_FIELDS = ['username'] 

    def __str__(self): 
     return "@{}".format(self.username) 

    def get_short_name(self): 
     return self.username 

    def get_long_name(self): 
     return "@{} ({})".format(self.username, self.email) 


class UserProfile(models.Model): 
    user = models.OneToOneField(settings.AUTH_USER_MODEL) 
    first_name = models.CharField(max_length=40, default='', blank=True) 
    last_name = models.CharField(max_length=40, default='', blank=True) 
    bio = models.TextField(blank=True, default='') 
    avatar = models.ImageField('Avatar picture', 
           upload_to=avatar_upload_path, 
           null=True, 
           blank=True) 
    skills = models.ManyToManyField(Skill) 

    def __str__(self): 
     return self.user.username 

    @property 
    def get_avatar_url(self): 
     if self.avatar: 
      return '/media/{}'.format(self.avatar) 
     return 'http://www.gravatar.com/avatar/{}?s=128&d=identicon'.format(
      '94d093eda664addd6e450d7e9881bcad' 
     ) 


def create_profile(sender, **kwargs): 
    if kwargs['created']: 
     user_profile = UserProfile.objects.create(user=kwargs['instance']) 

post_save.connect(create_profile, sender=User) 

并为我的项目应用程序在这里是模型。我想这也许是因为我在另一个应用程序中使用了从UserProfile到Skill类的多对多字段,所以我试图在两个应用程序上单独运行makemigrations ---在评论'技能'来自UserProfile。没有工作。所以不知道现在该做什么。

from django.conf import settings 
from django.db import models 

from django.core.urlresolvers import reverse 

class Skill(models.Model): 
    """User skills class.""" 
    ANDROID = 1 
    DESIGNER = 2 
    JAVA = 3 
    PHP = 4 
    PYTHON = 5 
    RAILS = 6 
    WORDPRESS = 7 
    IOS = 8 

    SKILL_CHOICES = (
     (str(ANDROID), 'Android Developer'), 
     (str(DESIGNER), 'Designer'), 
     (str(JAVA), 'Java Developer'), 
     (str(PHP), 'PHP Developer'), 
     (str(PYTHON), 'Python Developer'), 
     (str(RAILS), 'Rails Developer'), 
     (str(WORDPRESS), 'Wordpress Developer'), 
     (str(IOS), 'iOS Developer') 
    ) 

    name = models.CharField(max_length=140, choices=SKILL_CHOICES, default='unknown') 

    def __str__(self): 
     return self.get_name_display() 


class Project(models.Model): 
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='project', null=True) 
    created_at = models.DateTimeField(auto_now_add=True) 
    title = models.CharField(max_length=255) 
    description = models.TextField() 
    requirements = models.TextField(default='') 
    timeline = models.CharField(max_length=255, blank=True) 
    complete = models.BooleanField(default=False) 

    @property 
    def open_positions(self): 
     return self.positions.exclude(filled=True) 

    def __str__(self): 
     return self.title.title() 

    def get_absolute_url(self): 
     return reverse("projects:project_detail", kwargs={"pk": self.pk}) 


class Position(models.Model): 
    project = models.ForeignKey(Project, default='',related_name='positions') 
    name = models.CharField(max_length=140) 
    description = models.TextField() 
    skill = models.ForeignKey(Skill, default='', null=True) 
    filled = models.BooleanField(default=False) 

    def __str__(self): 
     return '{} - {}'.format(self.project.title.title(), self.name.title()) 
+0

您是否在帐户应用程序模型中导入了技能模型? – Exprator

+0

添加完整models.py代码与导入顶部的文件,并添加完整的回溯错误 –

+0

嗨加入所有进口---和是的,我没有进口技巧模型 –

回答

1

您的2个迁移对彼此具有依赖性。看看你的帐户的应用程序生成的迁移,你可能会看到这样的事情

class Migration(migrations.Migration): 

    dependencies = [ 
     ('projects', '0001_initial'), 
    ] 

有可能是在您的项目迁移类似

您需要删除这两个迁移文件,并再次运行makemigrations无指定应用程序名称

+0

是这样做的..谢谢你Iain! –

1

当你有这种类型的问题,这意味着你是相互导入类。您正在ForeignKey和ManytoMany字段中使用每个其他应用程序模型类。 因此,请使用下面的方式来定义两个应用程序的models.py中的字段。

field = models.ForeignKey('app_name.ModelClassName',) 
field = models.ManyToManyField('app_name.ModelClassName',) 
+0

感谢评论 - 但我不'真的看到我在做这件事的方式有什么不同? –

+0

您在代码中有循环依赖我想在运行python manage.py makemigrations时清除一个,然后创建迁移也与我提到的方式相同。 –