2017-07-25 75 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時清除一個,然後創建遷移也與我提到的方式相同。 –