我正在接管Django下的一个旧项目,但我不知道要使用的基本版本,在我的服务器上,我有1.9.9,我尝试通过docker进行构建,但是没有成功... < / p>
因此,我尝试将Django 1.x迁移到1.10,但是我目前对模型依赖存在疑问。当我启动应用程序时,我收到一条错误消息:
堆栈跟踪
web_1 | Traceback (most recent call last):
web_1 | File "./manage.py", line 9, in <module>
web_1 | execute_from_command_line(sys.argv)
web_1 | File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
web_1 | utility.execute()
web_1 | File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 341, in execute
web_1 | django.setup()
web_1 | File "/usr/local/lib/python2.7/site-packages/django/__init__.py", line 27, in setup
web_1 | apps.populate(settings.INSTALLED_APPS)
web_1 | File "/usr/local/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
web_1 | app_config.import_models(all_models)
web_1 | File "/usr/local/lib/python2.7/site-packages/django/apps/config.py", line 199, in import_models
web_1 | self.models_module = import_module(models_module_name)
web_1 | File "/usr/local/lib/python2.7/importlib/__init__.py", line 37, in import_module
web_1 | __import__(name)
web_1 | File "/usr/src/app/ots/geo/models.py", line 19, in <module>
web_1 | from ots.otsapi.models import RPCForeignKey
web_1 | File "/usr/src/app/ots/otsapi/models.py", line 4, in <module>
web_1 | from .fields import *
web_1 | File "/usr/src/app/ots/otsapi/fields.py", line 7, in <module>
web_1 | from django.db.models.fields.subclassing import Creator
web_1 | ImportError: No module named subclassing
我找不到子类和Creator的“替换”依赖项。
您知道我该怎么做吗?
requirement.txt
-e git://github.com/django-tastypie/django-tastypie.git@da9df5abcfcec1c0a659b179edcdfc0d3465e41c#egg=django-tastypie
-e git://github.com/python-babel/django-babel.git@5d953ef9e38ca5faf0ac4b39c9757aa87a40c00e#egg=django-babel
babel==2.2.0
BeautifulSoup>=3.2.1,<4.0.0
boto>=2.38.0,<3.0.0
cached-property==1.2.0
celery==3.1.23
crispy-forms-foundation==0.2.3.1
django-celery==3.1.17
django==1.10
django-modeltranslation==0.11
django-sortable>=0.3,<0.4
django-cacheback>=1.0,<2.0.0
django-filter==0.14
django-rest-auth>=0.9,<1
django-allauth>=0.24,<30
django-statsd-mozilla>=0.3,<1
drf-extensions>=0.2.8,<1.0.0
enum34>=1.0.4,<2.0.0
fastcache==1.0.2
freezegun==0.1.11
html5lib==0.95
iso8601==0.1.4
isodate==0.5.0
isoweek==1.3.0
kombu==3.0.37
libthumbor==1.0.1
markdown==2.2.1
mimeparse==0.1.3
mysqlclient==1.3.7
nameko==2.1.2
newrelic==2.60.0.46
pillow==2.5.1
purl==1.0
pypdf==1.13
python-cjson==1.0.5
python-dateutil==2.1
python-gettext==2.0
python-memcached==1.57
python-openid==2.2.5
python-updict==0.1.2
pytz==2015.7
raven==3.2.1
reportlab>=3.2.0,<4.0.0
requests>=2.8.1,<3.0.0
six>=1.10.0,<2.0.0
sorl-thumbnail==12.3
sphinx==1.1.3
statsd==1.0.0
tempdir==0.5
ua-parser==0.5.1
universal-analytics-python==0.2.4
user-agents==1.0.1
wsgiref>=0.1.2,<1.0.0
zerorpc==0.5.1
sqlparse>=0.1.18,<1.0.0 # required by extend migration 0003
python-geoip-geolite2==2015.0303
python-geoip-python3==1.3
hasattr-safe>=0.1.0,<1.0.0
django-fancy-cache>=0.8.0,<1.0.0
django-filer>=1.1.1,<2.0.0 # django-cms
cmsplugin-filer>=1.0.1,<2.0.0 # django-cms
django-reversion>=1.10.1,<2.0.0 # django-cms
djangocms-snippet>=1.7.1,<2.0.0 # django-cms
aldryn-newsblog==1.3.0 # django-cms-blog
django-cors-headers==1.2.2
django-oauth-toolkit==0.12.0
fields.py
from __future__ import absolute_import, unicode_literals
from django import forms
from django.db import models
from django.apps import apps
from django.core import exceptions
from django.db.models.fields.subclassing import Creator
# Mixin
class SortableMixin(object):
def __init__(self, *args, **kwargs):
self.sortable = kwargs.pop('sortable', False)
self.sortable_field = kwargs.pop('sortable_field', None)
super(SortableMixin, self).__init__(*args, **kwargs)
class IntegerField(SortableMixin, models.IntegerField):
__metaclass__ = models.SubfieldBase
class BooleanField(SortableMixin, models.BooleanField):
__metaclass__ = models.SubfieldBase
class NullBooleanField(SortableMixin, models.NullBooleanField):
__metaclass__ = models.SubfieldBase
class TextField(SortableMixin, models.TextField):
__metaclass__ = models.SubfieldBase
class CharField(SortableMixin, models.CharField):
__metaclass__ = models.SubfieldBase
class DateTimeField(SortableMixin, models.DateTimeField):
__metaclass__ = models.SubfieldBase
class TimeField(SortableMixin, models.TimeField):
__metaclass__ = models.SubfieldBase
class DecimalField(models.DecimalField):
__metaclass__ = models.SubfieldBase
class FloatField(models.FloatField):
__metaclass__ = models.SubfieldBase
class StringListField(models.Field):
__metaclass__ = models.SubfieldBase
default_error_messages = {
'invalid_list': 'Attribute should be a list',
}
def formfield(self, **kwargs):
defaults = {
'form_class': forms.CommaSeparatedField,
}
defaults.update(kwargs)
return super(StringListField, self).formfield(**defaults)
def clean(self, value, model_instance):
value = self.to_python(value)
self.validate(value, model_instance)
for v in value:
self.run_validators(v)
return value
def validate(self, value, model_instance):
if not isinstance(value, (list, tuple)):
raise exceptions.ValidationError(self.error_messages['invalid_list'])
return super(StringListField, self).validate(value, model_instance)
class LazyLookupFieldCreator(Creator):
def __init__(self, field):
self.field = field
self.cache_name = field.get_cache_name()
def __get__(self, instance, owner=None):
if instance is None:
return self
try:
rel_obj = getattr(instance, self.cache_name)
except AttributeError:
pk = instance.__dict__[self.field.attname]
if pk:
args = {
self.field._related_pk: pk
}
rel_obj = self.field._related_model_class.objects.get(**args)
else:
rel_obj = None
setattr(instance, self.cache_name, rel_obj)
return rel_obj
def __set__(self, instance, value):
setattr(instance, self.cache_name, value)
pk = getattr(value, self.field._related_pk)
instance.__dict__[self.field.attname] = pk
class LazyLookupFieldMeta(models.SubfieldBase):
def __new__(cls, name, bases, attrs):
def contribute_to_class(self, cls, name):
models.Field.contribute_to_class(self, cls, name)
setattr(cls, self.name, LazyLookupFieldCreator(self))
new_class = super(LazyLookupFieldMeta, cls).__new__(cls, name, bases, attrs)
new_class.contribute_to_class = contribute_to_class
return new_class
class LazyLookupField(models.Field):
__metaclass__ = LazyLookupFieldMeta
def __init__(self, related_field, related_model_class, pk="pk", *args, **kwargs):
self._related_field = related_field
self._related_model_class = self.get_related_model_class(related_model_class)
self._related_pk = pk
return super(LazyLookupField, self).__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super(LazyLookupField, self).deconstruct()
if self._related_field:
kwargs['related_field'] = self._related_field
if self._related_model_class:
kwargs['related_model_class'] = self._related_model_class
return name, path, args, kwargs
def get_related_model_class(self, related_model_class):
if not isinstance(related_model_class, basestring):
return related_model_class
if related_model_class == 'self':
return
try:
app, model = related_model_class.split('.')
except ValueError:
return
return apps.get_model(app, model)
def get_attname(self):
return self._related_field
def get_attname_column(self):
attname = self.get_attname()
return attname, attname
class PlatformModelChoiceField(forms.ModelChoiceField):
"""
A simple ModelChoiceField that assumes an integer based id
"""
def clean(self, value):
try:
value = int(value)
value = self.queryset.get(id=value)
except (ValueError, self.queryset.model.DoesNotExist):
raise forms.ValidationError('Invalid value supplied: {}'.format(value))
return value
class SimpleModelChoiceField(forms.ModelChoiceField):
"""
A simple ModelChoiceField that assumes an integer based id
"""
def clean(self, value):
if value:
return value
return None
class ReverseLazyLookupFieldCreator(Creator):
def __init__(self, field):
self.field = field
self.cache_name = field.get_cache_name()
def __get__(self, instance, owner=None):
if instance is None:
raise AttributeError('Can only be accessed via instance')
try:
value = getattr(instance, self.cache_name)
except AttributeError:
instance_value = getattr(instance, self.field.to_field, None)
model = self.field.get_related_model_class()
field_name = self.field.field_name
if instance_value:
try:
value = model.objects.get(**{
field_name: instance_value
})
except model.DoesNotExist:
if self.field.null:
value = None
else:
raise
setattr(instance, self.cache_name, value)
return value
def __set__(self, instance, value):
setattr(instance, self.cache_name, value)
class ReverseLazyLookupFieldMeta(models.SubfieldBase):
def __new__(cls, name, bases, attrs):
def contribute_to_class(self, cls, name):
self.set_attributes_from_name(name)
self.model = cls
cls._meta.add_field(self, virtual=True)
setattr(cls, self.name, ReverseLazyLookupFieldCreator(self))
new_class = super(ReverseLazyLookupFieldMeta, cls).__new__(cls, name, bases, attrs)
new_class.contribute_to_class = contribute_to_class
return new_class
class ReverseLazyLookupField(models.Field):
__metaclass__ = ReverseLazyLookupFieldMeta
def __init__(self, related_model, field_name, to_field='pk', **kwargs):
self.related_model = related_model
self.field_name = field_name
self.to_field = to_field
kwargs['editable'] = False
super(ReverseLazyLookupField, self).__init__(**kwargs)
def get_related_model_class(self):
if not isinstance(self.related_model, basestring):
return self.related_model
if self.related_model == 'self':
return
try:
app, model = self.related_model.split('.')
except ValueError:
return
return apps.get_model(app, model)
def get_attname(self):
return self.name
def get_attname_column(self):
attname = self.get_attname()
return attname, None
class RPCForeignKeyCreator(Creator):
def __init__(self, field):
self.field = field
self.cache_name = field.get_cache_name()
def __get__(self, instance, owner=None):
if instance is None:
return self
model_class = self.field.get_related_model_class()
try:
rel_obj = getattr(instance, self.cache_name)
except AttributeError:
pk = instance.__dict__[self.field.attname]
if pk is None and self.field.null:
return None
args = {
'pk': pk
}
rel_obj = getattr(model_class, self.field.manager_attr).get(**args)
setattr(instance, self.cache_name, rel_obj)
if rel_obj is None:
raise model_class.DoesNotExist()
return rel_obj
def __set__(self, instance, value):
if value is None:
instance.__dict__[self.field.attname] = None
return
setattr(instance, self.cache_name, value)
pk = getattr(value, 'pk')
instance.__dict__[self.field.attname] = pk
class RPCForeignKeyMeta(models.SubfieldBase):
def __new__(cls, name, bases, attrs):
def contribute_to_class(self, cls, name):
models.Field.contribute_to_class(self, cls, name)
setattr(cls, self.name, RPCForeignKeyCreator(self))
new_class = super(RPCForeignKeyMeta, cls).__new__(cls, name, bases, attrs)
new_class.contribute_to_class = contribute_to_class
return new_class
class RPCForeignKey(models.IntegerField):
__metaclass__ = RPCForeignKeyMeta
def __init__(self, related_model, manager_attr='objects', **kwargs):
self.related_model = related_model
self.manager_attr = manager_attr
super(RPCForeignKey, self).__init__(**kwargs)
def get_related_model_class(self):
if not isinstance(self.related_model, basestring):
return self.related_model
if self.related_model == 'self':
return
try:
app, model = self.related_model.split('.')
except ValueError:
return
return apps.get_model(app, model)
def get_attname(self):
return '%s_id' % self.name
def south_field_triple(self):
from south.modelsinspector import introspector
args, kwargs = introspector(self)
# We set these as None because they have no impact on the database,
# and real values confuse South
kwargs['related_model'] = None
kwargs['manager_attr'] = None
return (
'ots.otsapi.fields.RPCForeignKey',
args,
kwargs,
)
def deconstruct(self):
model_class_path = 'ots.otsapi.fields.RPCForeignKey'
name, path, args, kwargs = super(RPCForeignKey, self).deconstruct()
kwargs['related_model'] = None
kwargs['manager_attr'] = None
return name, model_class_path, args, kwargs