我见过Django 1.8 Migrations - "NoneType" object has no attribute "_meta"但是那里提出的解决方案似乎并非如此......
我正在研究Django应用程序,并且每次尝试运行“migrate”时都会收到此回溯(“makemigrations”工作正常,“syncdb”也是如此(如果我吹掉数据库并删除迁移文件夹) )。
(molivenv)moli@moli:~/moli$ ./manage.py migrate
Operations to perform:
Synchronize unmigrated apps: humanize, util, staticfiles, messages
Apply all migrations: core, contenttypes, sessions, admin, auth
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states...Traceback (most recent call last):
File "./manage.py", line 10, in
execute_from_command_line(sys.argv)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 221, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/db/migrations/executor.py", line 104, in migrate
state = migration.mutate_state(state, preserve=do_run)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/db/migrations/migration.py", line 83, in mutate_state
operation.state_forwards(self.app_label, new_state)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/db/migrations/operations/fields.py", line 51, in state_forwards
state.reload_model(app_label, self.model_name_lower)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/db/migrations/state.py", line 97, in reload_model
related_models = get_related_models_recursive(old_model)
File "/home/moli/moli/molivenv/lib/python3.4/site-packages/django/db/migrations/state.py", line 57, in get_related_models_recursive
rel_app_label, rel_model_name = rel_mod._meta.app_label, rel_mod._meta.model_name
AttributeError: 'NoneType' object has no attribute '_meta'
这些是我的模型(很抱歉这个长度,但我看不出任何关于追溯问题的暗示,所以我认为我会彻底):
from datetime import date
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from gm2m import GM2MField
from gm2m.deletion import DO_NOTHING
from localflavor.us.models import PhoneNumberField, USPostalCodeField, USZipCodeField
class Organization(models.Model):
is_active = models.BooleanField(blank=True, default=True)
name = models.CharField(max_length=255, help_text='For example, "Acme"', verbose_name="Short name")
full_legal_name = models.CharField(max_length=255, blank=True, help_text='For example, "Acme Widgets and Blivets, Inc."')
tax_id = models.CharField(max_length=100, blank=True, verbose_name="Tax ID")
website = models.URLField(blank=True)
address = models.ForeignKey('Address', blank=True, null=True, related_name="organization_address_set", verbose_name="Primary address")
mailing_address = models.ForeignKey('Address', blank=True, null=True, related_name="organization_mailing_address_set")
def __str__(self):
return self.name
@property
def model_verbose_name(self):
return self._meta.verbose_name
def get_mailing_address(self):
return self.mailing_address or self.address
def get_absolute_url(self):
return "/organizations/edit/%s/" % self.pk
class UserProfile(models.Model):
user = models.ForeignKey(User)
avatar = models.ImageField(blank=True, upload_to='user-avatars')
def __str__(self):
return str(self.user)
def avatar_url(self):
if self.avatar:
return self.avatar.url
else:
return "%suser-icon.png" % STATIC_URL
def get_absolute_url(self):
return "/users/%s/" % self.pk
class AuditedModel(models.Model):
added_on = models.DateTimeField(auto_now_add=True)
changed_on = models.DateTimeField(auto_now=True)
added_by = models.ForeignKey(UserProfile, blank=True, null=True)
organization = models.ForeignKey(Organization, blank=True, null=True, related_name="%(app_label)s_%(class)s_ownership")
is_active = models.BooleanField(blank=True, default=True)
class Meta:
abstract = True
@property
def model_verbose_name(self):
return self._meta.verbose_name
class Contact(AuditedModel):
first_name = models.CharField(max_length=255, blank=True)
middle_name = models.CharField(max_length=255, blank=True)
last_name = models.CharField(max_length=255)
photo = models.ImageField(blank=True, upload_to='contact_photos/', null=True, max_length=500)
dob = models.DateField(blank=True, verbose_name="DOB", null=True, help_text="Date of Birth")
dod = models.DateField(blank=True, verbose_name="DOD", null=True, help_text="Date of Death")
email = models.EmailField(blank=True)
office_phone = PhoneNumberField(blank=True)
home_phone = PhoneNumberField(blank=True)
mobile_phone = PhoneNumberField(blank=True)
other_phone = PhoneNumberField(blank=True)
fax = PhoneNumberField(blank=True)
skype = models.CharField(max_length=255, blank=True)
twitter = models.CharField(max_length=255, blank=True)
facebook = models.CharField(max_length=255, blank=True)
linkedin = models.CharField(max_length=255, blank=True, verbose_name="LinkedIn")
company = models.ForeignKey('Company', blank=True, null=True)
title = models.CharField(max_length=255, blank=True)
department = models.CharField(max_length=255, blank=True)
mailing_street = models.CharField(max_length=255, blank=True, verbose_name="Mailing Street")
mailing_city = models.CharField(max_length=255, blank=True, verbose_name="Mailing City")
mailing_state = USPostalCodeField(blank=True, verbose_name="Mailing State")
mailing_zip = USZipCodeField(blank=True, verbose_name="Mailing Zip")
comments = models.ManyToManyField('Comment', blank=True)
def __str__(self):
return " ".join([x for x in [self.get_prefix_display(), self.first_name, self.middle_name, self.last_name, self.get_suffix_display()] if x])
def photo_url(self):
if self.photo:
return self.photo.url
else:
return "%suser-icon.png" % STATIC_URL
def get_absolute_url(self):
return "/contacts/%s/" % self.pk
class Meta:
ordering = ['last_name', 'first_name', 'last_name']
class Company(AuditedModel):
name = models.CharField(max_length=255)
photo = models.ImageField(blank=True, upload_to='company_photos/', null=True, max_length=500)
email = models.EmailField(blank=True)
phone = PhoneNumberField(blank=True)
twitter = models.CharField(max_length=255, blank=True)
facebook = models.CharField(max_length=255, blank=True)
linkedin = models.CharField(max_length=255, blank=True, verbose_name="LinkedIn")
mailing_street = models.CharField(max_length=255, blank=True, verbose_name="Mailing Street")
mailing_city = models.CharField(max_length=255, blank=True, verbose_name="Mailing City")
mailing_state = USPostalCodeField(blank=True, verbose_name="Mailing State")
mailing_zip = USZipCodeField(blank=True, verbose_name="Mailing Zip")
other_street = models.CharField(max_length=255, blank=True, verbose_name="Other Street")
other_city = models.CharField(max_length=255, blank=True, verbose_name="Other City")
other_state = USPostalCodeField(blank=True, verbose_name="Other State")
other_zip = USZipCodeField(blank=True, verbose_name="Other ZIP")
comments = models.ManyToManyField('Comment', blank=True)
def __str__(self):
return self.name
def photo_url(self):
if self.photo:
return self.photo.url
else:
return "%scompany-icon.png" % STATIC_URL
def get_absolute_url(self):
return "/companies/%s/" % self.pk
class Meta:
ordering = ['name',]
class Comment(AuditedModel):
comment = models.TextField()
def __str__(self):
return "Comment made on %s by %s" % (self.added_on, self.added_by)
class Meta:
ordering = ['-added_on',]
class Address(AuditedModel):
street = models.CharField(max_length=255)
city = models.CharField(max_length=255)
state = USPostalCodeField()
zip = USZipCodeField(blank=True, verbose_name="ZIP")
def __str__(self):
return "%s, %s, %s%s" % (self.street, self.city, self.state, self.zip and " %s" % self.zip or '')
def associated(self):
ret = [] # Could use yield, but template doesn't let you do |length then...
for c in self.organization_address_set.all():
ret.append({'model': Organization, 'instance': c, 'field': 'address', 'field_display': 'Primary Address'})
for c in self.organization_mailing_address_set.all():
ret.append({'model': Organization, 'instance': c, 'field': 'mailing_address', 'field_display': 'Mailing Address'})
return ret
class Photo(AuditedModel):
photo = models.ImageField(upload_to='photo-library/')
caption = models.CharField(blank=True, max_length=500)
def __str__(self):
return self.caption or self.photo.file.name
class UserFile(AuditedModel):
file = models.FileField(upload_to='user-files/')
description = models.CharField(blank=True, max_length=500)
def __str__(self):
return self.description or self.file.file.name
class Item(AuditedModel):
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
item_number = models.CharField(max_length=255, blank=True)
main_photo = models.ForeignKey('Photo', blank=True, null=True, related_name="%(app_label)s_%(class)s_ownership")
other_photos = models.ManyToManyField('Photo', blank=True, related_name="%(app_label)s_%(class)s_other_ownership")
attachments = models.ManyToManyField('UserFile', blank=True)
comments = models.TextField(blank=True)
class Meta:
abstract = True
class RawMaterial(Item):
supplier = models.ForeignKey(Company, blank=True, null=True)
spn = models.CharField(max_length=255, blank=True, help_text="Supplier's Part Number")
inventoried = models.BooleanField(blank=True, default=True)
um = models.ForeignKey('UnitOfMeasure', blank=True, null=True)
def __str__(self):
return self.name
class RawMaterialQuantity(AuditedModel):
raw_material = models.ForeignKey('RawMaterial')
qty = models.DecimalField(decimal_places=5, max_digits=50)
unit = models.ForeignKey('UnitOfMeasure', blank=True, null=True)
def __str__(self):
return "%s %s of %s" % (self.qty, self.unit, self.raw_material)
class PurchasedRawMaterial(AuditedModel):
raw_material_quantity = models.ForeignKey('RawMaterialQuantity')
price = models.DecimalField(decimal_places=2, max_digits=50)
purchase_date = models.DateField()
lot_number = models.CharField(max_length=255, blank=True)
def __str__(self):
if self.lot_number:
return "%s purchased on %s (lot #%s)" % (self.raw_material_quantity, self.purchase_date, self.lot_number)
else:
return "%s purchased on %s" % (self.raw_material_quantity, self.purchase_date)
class UnitOfMeasure(AuditedModel):
name = models.CharField(max_length=255, help_text="For example, 'Ounces'")
abbreviation = models.CharField(max_length=40, help_text="For example, 'Oz.'")
def __str__(self):
return self.abbreviation
class Meta:
ordering = ['abbreviation',]
class Assembly(Item):
mpn = models.CharField(max_length=255, blank=True, help_text="Manufacturer's Part Number") # If purchased
price = models.DecimalField(decimal_places=2, max_digits=50, null=True) # If purchased
production_steps = models.ManyToManyField('ProductionStep', blank=True) # If made
def __str__(self):
return self.name
class PurchasedAssembly(AuditedModel):
assembly = models.ForeignKey('Assembly')
purchase_price = models.DecimalField(decimal_places=2, max_digits=50)
purchase_date = models.DateField()
serial_number = models.CharField(max_length=255, blank=True)
def __str__(self):
if self.serial_number:
return "%s purchased on %s (serial #%s)" % (self.assembly, self.purchase_date, self.serial_number)
else:
return "%s purchased on %s" % (self.assembly, self.purchase_date)
class AssembledAssembly(AuditedModel):
assembly = models.ForeignKey('Assembly')
assembly_date = models.DateField()
serial_number = models.CharField(max_length=255, blank=True)
def __str__(self):
if self.serial_number:
return "%s assembled on %s (serial #%s)" % (self.assembly, self.assembly_date, self.serial_number)
else:
return "%s assembled on %s" % (self.assembly, self.assembly_date)
class AssemblyQuantity(AuditedModel):
assembly_type = models.ForeignKey(ContentType)
assembly_id = models.PositiveIntegerField()
assembly_object = GenericForeignKey('assembly_type', 'assembly_id')
qty = models.DecimalField(decimal_places=5, max_digits=50)
def __str__(self):
return "%s %s" % (self.qty, self.assembly_object.name)
class Product(Item):
resell = models.BooleanField(default=False, help_text="Do you resell this item (rather than make it)?")
mpn = models.CharField(max_length=255, blank=True, help_text="Manufacturer's Part Number")
price = models.DecimalField(decimal_places=2, max_digits=50, null=True)
production_steps = models.ManyToManyField('ProductionStep', blank=True)
def __str__(self):
return self.name
class ProductionStep(models.Model):
order = models.IntegerField()
time = models.DecimalField(help_text="How much time does this step take, in minutes?", decimal_places=5, max_digits=50)
materials = GM2MField(on_delete=DO_NOTHING, blank=True) # RawMaterialQuantity, AssemblyQuantity
def __str__(self):
return "Step %s" % self.order
GM2MField来自https://pypi.python.org/pypi/django-gm2m/