Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django makemigrations AttributeError: 'str' object has no attribute '_meta'

I was playing with the django framework and I ran into an issue running the makemigration command. Here is a copy of the model and the stack trace it produces. I have seen a couple of posts with the same error but none has led me to resolve my problem here. I am working with django 1.9.4

from django.db import models
import os, uuid

# Create your models here.
def video_directory_path(instance, folder):
    return os.path.join('video', str(instance.person.id), str(instance.video_id))

def photo_directory_path(instance, folder):
        return os.path.join('image', str(instance.person.id), str(instance.photo_id))


class Image(models.Model):
    name = models.CharField(max_length=128)
    photo_id = models.UUIDField(verbose_name='photo id', default=uuid.uuid4, editable=False, unique=True)
    photo = models.ImageField(upload_to=photo_directory_path)
    person = models.ForeignKey('Person', on_delete=models.CASCADE)
    movie = models.ForeignKey('Movie', on_delete=models.CASCADE)

    class Meta:
        db_table = 'Image'

    def __str__(self):
        return '[{0}- {1}]'.format(self.__class__.__name__, self.id)

    def __repr__(self):
        return self.__str__()


class Video(models.Model):
    name = models.CharField(max_length=128)
    video_id = models.UUIDField(verbose_name='video id', default=uuid.uuid4, editable=False, unique=True)
    video = models.FileField(upload_to=video_directory_path)
    person = models.ForeignKey('Person', on_delete=models.CASCADE)
    movie = models.ForeignKey('Movie', on_delete=models.CASCADE)

    class Meta:
        db_table = 'Video'

    def __str__(self):
        return '[{0}-{1}]'.format(self.__class__.__name__, self.id)

    def __repr__(self):
        return self.__str__()


class Filmography(models.Model):
    filmography = models.CharField(max_length=128, db_index=True)

    class Meta:
        db_table = 'Filmography'

    def __str__(self):
        return '[{0}-{1}]'.format(self.__class__.__name__, self.id)

    def __repr__(self):
        return self.__str__()


class Person(models.Model):
    bio = models.TextField()
    filmography = models.ManyToManyField('Filmography')
    photos = models.ManyToManyField(
        'Image',
        through='ImagePerson',
        through_fields=('person', 'photo')
    )

    class Meta:
        abstract = True

    def __str__(self):
        return '[{0}-{1}]'.format(self.__class__.__name__, self.id)

    def __repr__(self):
        return self.__str__()


class Profile(Person):
    first_name = models.CharField(max_length=128, verbose_name="first name")
    last_name = models.CharField(max_length=128, verbose_name="last name")
    dob = models.DateField()

    class Meta:
        index_together = ["first_name", "last_name"]
        db_table = 'Profile'


class Character(Person):
    name = models.CharField(max_length=128)

    class Meta:
        db_table = 'Character'


class Crew(models.Model):
    name = models.CharField(max_length=256)
    members = models.ManyToManyField(
        'Profile',
        through='MovieCrew',
        through_fields=('crew', 'profile'),
    )

    class Meta:
        db_table = 'Crew'

        def __str__(self):
            return '{0}: {1}'.format(self.__class__.__name__, self.name)

    def __repr__(self):
        return self.__str__()


class MovieCrew(models.Model):
    crew = models.ForeignKey(
        'Crew',
        on_delete=models.CASCADE,
    )
    profile = models.ForeignKey(
        'Profile',
        on_delete=models.CASCADE,
    )
    role = models.CharField(max_length=256)

    class Meta:
        db_table = 'MovieCrew'


class Genre(models.Model):
    genre = models.CharField(max_length=128, db_index=True)

    class Meta:
        db_table = 'Genre'


class Movie(models.Model):
    name = models.CharField(max_length=128, db_index=True)
    summary = models.CharField(max_length=256)
    story = models.CharField(max_length=256)
    release_date = models.DateField()

    crew = models.OneToOneField(
        'Crew',
        on_delete=models.CASCADE,
    )
    genre = models.ManyToManyField('Genre')
    photos = models.ManyToManyField('Image')
    videos = models.ManyToManyField('Video')

    class Meta:
        db_table = 'Movie'
        get_latest_by = 'release_date'

    def __str__(self):
        return '[{0}-{1}]'.format(self.__class__.__name__, self.name)

    def __repr__(self):
        return self.__str__()

and the error stacktrace

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Python34\lib\site-packages\django\core\management\__init__.py", line 353, in execute_from_command_line
    utility.execute()
  File "C:\Python34\lib\site-packages\django\core\management\__init__.py", line 345, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Python34\lib\site-packages\django\core\management\base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Python34\lib\site-packages\django\core\management\base.py", line 398, in execute
    self.check()
  File "C:\Python34\lib\site-packages\django\core\management\base.py", line 426, in check
    include_deployment_checks=include_deployment_checks,
  File "C:\Python34\lib\site-packages\django\core\checks\registry.py", line 75, in run_checks
    new_errors = check(app_configs=app_configs)
  File "C:\Python34\lib\site-packages\django\core\checks\model_checks.py", line 28, in check_all_models
    errors.extend(model.check(**kwargs))
  File "C:\Python34\lib\site-packages\django\db\models\base.py", line 1170, in check
    errors.extend(cls._check_fields(**kwargs))
  File "C:\Python34\lib\site-packages\django\db\models\base.py", line 1249, in _check_fields
    errors.extend(field.check(from_model=cls, **kwargs))
  File "C:\Python34\lib\site-packages\django\db\models\fields\related.py", line 1165, in check
    errors.extend(self._check_relationship_model(**kwargs))
  File "C:\Python34\lib\site-packages\django\db\models\fields\related.py", line 1366, in _check_relationship_model
    for f in through._meta.fields:
AttributeError: 'str' object has no attribute '_meta'
like image 795
legend Avatar asked Apr 04 '16 01:04

legend


4 Answers

make sure you did python manage.py makemigrations and python manage.py migrate

if you already did it then check

in serializers.py

class Meta:
    model = 'bla bla' 
    fields = '__all__'

I got this error when i wrote model name in string ('') if you did same mistake then check and remove ''

like image 76
Sushang Agnihotri Avatar answered Oct 18 '22 07:10

Sushang Agnihotri


There doesn't seem to be a class named ImagePerson in that file which is what you are setting the through (the through table) to be in the M2M on Person.

like image 36
dreamriver Avatar answered Oct 18 '22 06:10

dreamriver


Indentation problem on your Crew class? Your str method here seems to be defined on the Meta:

class Crew(models.Model):
    name = models.CharField(max_length=256)
    members = models.ManyToManyField(
        'Profile',
        through='MovieCrew',
        through_fields=('crew', 'profile'),
    )

    class Meta:
        db_table = 'Crew'


        def __str__(self):
            return '{0}: {1}'.format(self.__class__.__name__, self.name)

    def __repr__(self):
        return self.__str__()

Is that really what you're after?

like image 20
kjarsenal Avatar answered Oct 18 '22 06:10

kjarsenal


For some people getting this error, don't forget to add a newly created app into Django's INSTALLED_APPS for your ManyToMany's through= intermediary model to be recognized.

like image 36
sivabudh Avatar answered Oct 18 '22 08:10

sivabudh