从Django 1.8升级到1.9时发生ValueError

时间:2019-04-26 11:51:21

标签: python django upgrade django-1.9

我最近将一个项目从1.8.11升级到1.9,一切在1.8上都可以正常工作,并且我已经通过了弃用警告并清理了项目中的许多内容。

当我尝试运行项目时出现错误

ValueError: Cannot create form field for 'country' yet, because its related model 'Country' has not been
loaded yet

我已经尝试解决了几个小时,非常感谢您的帮助

我浏览了Django网站上的升级说明,升级了一些依赖项,这些依赖项修复了一个或两个警告,但仍未解决问题。

User = settings.AUTH_USER_MODEL
class Country(TimeStampedModel):
    name = models.CharField(max_length=50, unique=True)
    code = models.CharField(max_length=2, null=True, blank=True, db_index=True)
    code3 = models.CharField(max_length=3, null=True, blank=True, unique=True)
    last_updated_by = models.ForeignKey(User, null=True, blank=True, related_name='%(class)s_last_updated_by')
    created_by = models.ForeignKey(User, default=settings.SYSTEM_USER_ID, related_name='%(class)s_created_by')

    objects = models.Manager()
    countries = CountryManager()

    class Meta:
        verbose_name = _('country')
        verbose_name_plural = _('countries')
        ordering = ['name']

    def __str__(self):
        return self.name

class AddressAbstractModel(TimeStampedModel):
    country = models.ForeignKey('Country', verbose_name=_('country'), null=True, blank=True)
    address_1 = models.CharField(_('street address line 1'), max_length=50, blank=True)
    address_2 = models.CharField(_('street address line 2'), max_length=50, blank=True)
    city = models.CharField(_('city'), max_length=50, blank=True)
    postal_code = models.CharField(_('postal code'), max_length=20, blank=True)
    latitude = models.DecimalField(_('Latitude'), max_digits=9, decimal_places=6, null=True, blank=True)
    longitude = models.DecimalField(_('Longitude'), max_digits=9, decimal_places=6, null=True, blank=True)

    class Meta:
        abstract = True

表格


User = get_user_model()

class UserChangeForm(forms.UserChangeForm):
    class Meta:
        model = User
        fields = '__all__'
        help_texts = {
            'username': _('Required. Letters, digits and @/./+/-/_ only.')
        }


class UserCreationForm(forms.UserCreationForm):
    class Meta:
        model = User
        fields = ("username",)
        help_texts = {
            'username': _('Required. Letters, digits and @/./+/-/_ only.')
        }

编辑:请求完全回溯

web_1_1b9067fcd9a4 | Traceback (most recent call last):
web_1_1b9067fcd9a4 |   File "manage.py", line 10, in <module>
web_1_1b9067fcd9a4 |     execute_from_command_line(sys.argv)
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/core/management/__init__.py", line 350, in execute_
from_command_line
web_1_1b9067fcd9a4 |     utility.execute()
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/core/management/__init__.py", line 324, in execute
web_1_1b9067fcd9a4 |     django.setup()
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/__init__.py", line 18, in setup
web_1_1b9067fcd9a4 |     apps.populate(settings.INSTALLED_APPS)
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/apps/registry.py", line 115, in populate
web_1_1b9067fcd9a4 |     app_config.ready()
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/contrib/admin/apps.py", line 22, in ready
web_1_1b9067fcd9a4 |     self.module.autodiscover()
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/contrib/admin/__init__.py", line 26, in autodiscove
r
web_1_1b9067fcd9a4 |     autodiscover_modules('admin', register_to=site)
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/utils/module_loading.py", line 50, in autodiscover_
modules
web_1_1b9067fcd9a4 |     import_module('%s.%s' % (app_config.name, module_to_search))
web_1_1b9067fcd9a4 |   File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
web_1_1b9067fcd9a4 |     return _bootstrap._gcd_import(name[level:], package, level)
web_1_1b9067fcd9a4 |   File "<frozen importlib._bootstrap>", line 994, in _gcd_import
web_1_1b9067fcd9a4 |   File "<frozen importlib._bootstrap>", line 971, in _find_and_load
web_1_1b9067fcd9a4 |   File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
web_1_1b9067fcd9a4 |   File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
web_1_1b9067fcd9a4 |   File "<frozen importlib._bootstrap_external>", line 678, in exec_module
web_1_1b9067fcd9a4 |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
web_1_1b9067fcd9a4 |   File "winda/users/admin.py", line 11, in <module>
web_1_1b9067fcd9a4 |     from .forms import UserChangeForm, UserCreationForm
web_1_1b9067fcd9a4 |   File "winda/users/forms.py", line 5, in <module>
web_1_1b9067fcd9a4 |     class UserChangeForm(forms.UserChangeForm):
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/forms/models.py", line 247, in __new__
web_1_1b9067fcd9a4 |     opts.field_classes)
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/forms/models.py", line 172, in fields_for_model
web_1_1b9067fcd9a4 |     formfield = f.formfield(**kwargs)
web_1_1b9067fcd9a4 |   File "/usr/local/lib/python3.6/dist-packages/django/db/models/fields/related.py", line 937, in formfiel
d
web_1_1b9067fcd9a4 |     (self.name, self.remote_field.model))
web_1_1b9067fcd9a4 | ValueError: Cannot create form field for 'country' yet, because its related model 'Country' has not been
loaded yet

已安装的应用程序

DJANGO_APPS = (
    # Default Django apps:
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Useful template tags:
    # 'django.contrib.humanize',

    # Admin
    'django.contrib.admin',
    'django.contrib.flatpages',
)
THIRD_PARTY_APPS = (
    'widget_tweaks',
    'storages',
    'reversion',
    'django_ses',
    'timezone_field',
    'ckeditor',
    'ckeditor_uploader',
    'rest_framework',
    'rest_framework.authtoken',
    'solo',
    'phonenumber_field',
    'allauth',
)

# Apps specific for this project go here.
LOCAL_APPS = (
    # Your stuff: custom apps go here
    'core',
    'users',
    'common',
    'registration',
    'trainings',
    'courses',
    'delegate',
    'organization',
    'database_admin',
    'database_super_admin',
    'orders',
    'api',
)

用户模式

class User(AbstractBaseUser, PermissionsMixin, UserProfileAbstract):

    UNKNOWN, BOUNCE, COMPLAINT, DELIVERY = 'Unknown', 'Bounce', 'Complaint', 'Delivery'

    EMAIL_STATUS_CHOICE = (
        (UNKNOWN, 'Unknown'),
        (BOUNCE, 'Bounce'),
        (COMPLAINT, 'Complaint'),
        (DELIVERY, 'Delivery')
    )

    delegate_id = models.CharField(_('delegate id'), unique=True, max_length=12, null=True, default=None, db_index=True)
    expires_at = models.DateTimeField(_('expires at'), default=TimeStampedModel.user_expires_at_default)
    email_status = models.CharField(_('email status'), max_length=10, choices=EMAIL_STATUS_CHOICE)
    role = models.CharField(_('role'), max_length=30, choices=UserProfileAbstract.ROLE_CHOICE, db_index=True)
    company_name = models.CharField(_('company name'), max_length=50, blank=True)
    last_updated_by = models.ForeignKey('self', default=settings.SYSTEM_USER_ID, null=True, related_name='%(class)s_last_updated_by')
    created_by = models.ForeignKey('self', default=settings.SYSTEM_USER_ID, null=True, related_name='%(class)s_created_by')
    archived_by = models.ForeignKey('self', null=True, related_name='%(class)s_archived_by', blank=True)
    can_upload = models.BooleanField(_('can upload files'), default=False)
    can_buy_credit = models.BooleanField(_('can buy credits'), default=False)
    can_use_credit = models.BooleanField(_('can use credits'), default=False)
    can_ask_revoke = models.BooleanField(_('can ask to request certificate revokes'), default=False)
    is_tp_site_access = models.BooleanField(_('Access to all TP site profiles'), default=False)
    api_rate_limit = models.IntegerField(_('daily API request limit'), default=settings.API_CALL_RATE_LIMIT, blank=True)
    is_api_enabled = models.BooleanField(_('API enabled'), default=False, blank=True)

    username = models.CharField(_('username'), max_length=255, unique=True,
        help_text=_('Required. 255 characters or fewer. Letters, digits and '
                    '@/./+/-/_ only.'),
        validators=[
            validators.RegexValidator(r'^[\w.@+-]+$',
                                      _('Enter a valid username. '
                                        'This value may contain only letters, numbers '
                                        'and @/./+/-/_ characters.'), 'invalid'),
        ],
        error_messages={
            'unique': _("A user with that username already exists."),
        })
    first_name = models.CharField(_('first name(s)'), max_length=100, blank=False)
    last_name = models.CharField(_('surname'), max_length=100, blank=False)
    email = models.EmailField(_('email address'), blank=False, max_length=255)
    is_staff = models.BooleanField(_('staff status'), default=False,
        help_text=_('Designates whether the user can log into this admin '
                    'site.'))
    is_active = models.BooleanField(_('active'), default=True,
        help_text=_('Designates whether this user should be treated as '
                    'active. Unselect this instead of deleting accounts.'))
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = WindaUserManager()

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

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

    def __str__(self):
        return self.username


class UserProfileAbstract(AddressAbstractModel):


    archived_from = models.DateTimeField(_('archived from'), default=TimeStampedModel.archived_from_default)
    archived_at = models.DateTimeField(_('archived at'), null=True, blank=True)
    job_title = models.CharField(_('job title'), max_length=50, blank=True)
    organization_name = models.CharField(_('organisation name'), max_length=200, blank=True)
    training_provider = models.ForeignKey(TrainingProvider, verbose_name=_('training provider'), null=True, blank=True,
                                          related_name='%(class)s_users')
    phone = models.CharField(_('work phone number'), max_length=15, blank=True)
    timezone = TimeZoneField(default='Europe/London')

    class Meta:
        abstract = True

1 个答案:

答案 0 :(得分:1)

您遇到了问题#25858。当AddressAbstractModel模型使用users.User时,'Country'解析为users.Country,它不存在。

您可以通过在抽象模型的外键中使用common.Country来解决问题。

有关更多信息,请参见foreign key docs中的示例。