2015-05-27 16 views
7

Jestem modelami kompilacji w Django 1.8 i używam dziedziczenia abstrakcyjnego (co, jak przypuszczam, przyczynia się do problem). Mam modele abstrakcyjne, a następnie mam modele oparte na tych abstrakcyjnych modelach. Mam również powiązania ForeignKey i ManyToMany między niektórymi modelami.Obiekt "NoneType" nie ma atrybutu "unique", ALE nie używam atrybutu "unique"

Wszystko wygląda dobrze, ale kiedy próbuję wykonać syncdb lub "makemigrations blog", otrzymuję atrybut AttributeError, który mówi, że obiekt "NoneType" nie ma atrybutu "unique".

Nie wiem, dlaczego to rozumiem, i próbowałem eksperymentować z różnymi konfiguracjami modeli, czytałem wiele postów na forum, ale na razie uderzyłem w ścianę.

wyślę na traceback i moje modele poniżej:

modele:

indie_db

from django.db import models 

class URL(models.Model): 
    link = models.CharField(max_length=400) 
    name = models.CharField(max_length=200) 

    def __str__(self): 
     return self.name 


class Artist(models.Model): 
    name = models.CharField(max_length=200) 
    description = models.TextField(null=True, blank=True) 
    link = models.ForeignKey(URL) 

    class Meta: 
     abstract = True 
     ordering = ['name'] 

    def __str__(self): 
     return self.name 


class ArtistSingle(Artist): 
    birthdate = models.DateField(null=True, blank=True) 
    deathdate = models.DateField(null=True, blank=True) 


class ArtistGroup(Artist): 
    members = models.ManyToManyField(ArtistSingle) 
    established = models.DateField(null=True, blank=True) 
    disbanded = models.DateField(null=True, blank=True) 


class Contributor(models.Model): 
    contributing_artist = models.ForeignKey(ArtistSingle, null=True, blank=True) 
    alternate_name = models.CharField(max_length=200) 
    role = models.CharField(max_length=200) 


class ProductionCompany(models.Model): 
    name = models.CharField(max_length=200) 
    link = models.ForeignKey(URL) 

    def __str__(self): 
     return self.name 


class Work(models.Model): 
    title = models.CharField(max_length=200) 
    description = models.TextField(null=True, blank=True) 
    created = models.DateField() 
    city = models.CharField(max_length=200) 
    production_company = models.ForeignKey(ProductionCompany, blank=True, null=True) 
    self_published = models.BooleanField(default=False) 
    creator = models.ForeignKey(Artist) 
    link = models.ForeignKey(URL) 
    styles = models.CharField(max_length=200) 
    contributors = models.ManyToManyField(Contributor) 

    class Meta: 
     abstract = True 
     ordering = ['-created'] 

    def __str__(self): 
     return self.title 


class MusicalWork(Work): 
    audio_links = models.ManyToManyField(URL) 


class WrittenWork(Work): 
    excerpt = models.TextField(null=True, blank=True) 


class PerformanceWork(Work): 
    venue = models.CharField(max_length=200) 


class VideoWork(Work): 
    length = models.CharField(max_length=16) 


class VisualWork(Work): 
    images = models.ManyToManyField(URL) 

blog:

from django.db import models 

# Create your models here. 


class Tag(models.Model): 
    tag_name = models.CharField(max_length=200) 

    def __str__(self): 
     return self.tag_name 


class Entry(models.Model): 
    title = models.CharField(max_length=200) 
    body = models.TextField() 
    slug = models.SlugField(max_length=200) 
    publish = models.BooleanField(default=True) 
    created = models.DateTimeField(auto_now=True) 
    modified = models.DateTimeField(auto_now=True) 
    tags = models.ManyToManyField(Tag) 

    def __str__(self): 
     return self.title 

    class Meta: 
     verbose_name = "Blog Entry" 
     verbose_name_plural = "Blog Entries" 
     ordering = ["-created"] 

Traceback:

[[email protected] weird_canada]$ python3.4 manage.py makemigrations blog 
Traceback (most recent call last): 
    File "manage.py", line 10, in <module> 
    execute_from_command_line(sys.argv) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/__init__.py", line 338, in execute_from_command_line 
    utility.execute() 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/__init__.py", line 330, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/base.py", line 390, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/base.py", line 440, in execute 
    self.check() 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/base.py", line 478, in check 
    include_deployment_checks=include_deployment_checks, 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/checks/registry.py", line 72, in run_checks 
    new_errors = check(app_configs=app_configs) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/checks/model_checks.py", line 28, in check_all_models 
    errors.extend(model.check(**kwargs)) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/base.py", line 1181, in check 
    errors.extend(cls._check_fields(**kwargs)) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/base.py", line 1258, in _check_fields 
    errors.extend(field.check(**kwargs)) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/fields/related.py", line 1829, in check 
    errors = super(ForeignKey, self).check(**kwargs) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/fields/related.py", line 1502, in check 
    errors.extend(self._check_unique_target()) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/fields/related.py", line 1522, in _check_unique_target 
    for rel_field in self.foreign_related_fields) 
    File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/fields/related.py", line 1522, in <genexpr> 
    for rel_field in self.foreign_related_fields) 
AttributeError: 'NoneType' object has no attribute 'unique' 

JEŚLI to jest spowodowane przez moje odziedziczone modele, jaka jest dokładna przyczyna i jak mam to zmienić?

Z góry dziękuję.

+1

Jestem stoi dokładnie ten sam problem. Znalazłeś rozwiązanie? Czy możesz nam o tym powiedzieć? – cpury

Odpowiedz

3

Uważam, że problem dotyczy modeli Work.

Masz ForeignKey do URL w abstrakcyjnej klasie

link = models.ForeignKey(URL) 

I masz też klucze do URL w niektórych klasach pochodnych, np MusicalWork:

class MusicalWork(Work): 
    audio_links = models.ManyToManyField(URL) 

Więc MusicalWork ma dwa linki do adresu URL. Co byłoby w porządku, poza tym, że Django próbuje stworzyć odwrotną relację adresu URL do twojego modelu, zwykle nazywaną musicalwork_set dla tego przypadku, ale ma dwie odwrotne relacje dla tego samego modelu!

Odpowiedzią byłoby określenie pola related_name dla modeli, które pochodzą z niego z tymi samymi odniesieniami do modelu.

Dlatego:

class MusicalWork(Work): 
    audio_links = models.ManyToManyField(URL, related_name='musicalwork_audio_set') 

Ale mogą pojawić się inne problemy, jak komunikat o błędzie nie dokładnie wskazać tego warunku (uwierzcie mi, Django ma znacznie ładniejszy komunikat o błędzie dla tego konkretnego błędu).

+0

Dlaczego ludzie martwią się? Problem z pewnością nie określał "powiązanej nazwy", podczas gdy miał wiele konfliktowych odwrotnych relacji ... –

1

Dzieje się tak, ponieważ masz klucz obcy do modelu abstrakcyjnego.

creator = models.ForeignKey(Artist) 

można zmienić na ArtistSingle

creator = models.ForeignKey(ArtistSingle) 

Idealnie powinno być wyrzucane właściwego błędu jak

Pole definiuje relację z modelu „Artist”, które nie zostało zainstalowane lub jest abstrakcyjna.

Ale katastrofa jest bug with Django 1.8

Powiązane problemy