Форум сайта python.su
Всех приветствую.
Помогите пожалуйста.
Есть 2 аппликухи
# app_places from django.db import models class Place(models.Model): movie = models.ManyToManyField('app_shows_and_times.Show', through='app_shows_and_times.Showtime') place_name = models.CharField(max_length=50, db_index=True) place_street = models.CharField('Street', max_length=80) place_phone = models.CharField('Phone', max_length=60) class Meta: db_table = 'place'
# app_shows_and_times from django.db import models class Show(models.Model): show_name = models.CharField(max_length=100, db_index=True) class Meta: db_table = 'show' class Showtime(models.Model): showtime_dates = models.CharField('Date', max_length=30) showtime_times = models.CharField('Time', max_length=30) showtime_place = models.ForeignKey('app_places.Place', verbose_name='Place') showtime_show = models.ForeignKey(Show, verbose_name='Show name') class Meta: db_table = 'showtime'
Traceback (most recent call last): File "manage.py", line 10, in <module> execute_from_command_line(sys.argv) File "/home/antonio/projects/my_site/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line utility.execute() File "/home/antonio/projects/my_site/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/antonio/projects/my_site/lib/python3.4/site-packages/django/core/management/base.py", line 393, in run_from_argv self.execute(*args, **cmd_options) File "/home/antonio/projects/my_site/lib/python3.4/site-packages/django/core/management/base.py", line 444, in execute output = self.handle(*args, **options) File "/home/antonio/projects/my_site/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 146, in handle plan = executor.migration_plan(targets) File "/home/antonio/projects/my_site/lib/python3.4/site-packages/django/db/migrations/executor.py", line 59, in migration_plan for migration in self.loader.graph.forwards_plan(target): File "/home/antonio/projects/my_site/lib/python3.4/site-packages/django/db/migrations/graph.py", line 139, in forwards_plan self.ensure_not_cyclic(node, lambda x: (parent.key for parent in self.node_map[x].parents)) File "/home/antonio/projects/my_site/lib/python3.4/site-packages/django/db/migrations/graph.py", line 196, in ensure_not_cyclic raise CircularDependencyError(", ".join("%s.%s" % n for n in cycle)) django.db.migrations.graph.CircularDependencyError: app_shows_and_times.0001_initial, app_places.0001_initial
movie = models.ManyToManyField('app_shows_and_times.Show', through='app_shows_and_times.Showtime')
movie = models.ManyToManyField('app_shows_and_times.Show', through='app_shows_and_times.Showtime')
Отредактировано TitanFighter (Сен. 15, 2015 16:25:41)
Офлайн
У вас уже есть M2M связь таблиц Place и ShowTime, вы делаете еще одну связь
showtime_show = models.ForeignKey(Show, verbose_name='Show name')
Офлайн
Добрый день FishHook
Мои странные связи сделаны исходя из документации
+ в данной теме в посте №7 товарищ PooH сказал, что все верно (с поправкой на то, что он подзабыл Джангу).
Я что-то недопонимаю?
Отредактировано TitanFighter (Сен. 13, 2015 12:53:17)
Офлайн
TitanFighterМне так кажется.
Я что-то недопонимаю?
movie = models.ManyToManyField('app_shows_and_times.Show', through='app_shows_and_times.Showtime')
showtime_place = models.ForeignKey('app_places.Place', verbose_name='Place')
Офлайн
Логически я понимаю о чем вы говорите, но в документации почему то указано это повторение:
from django.db import models class Person(models.Model): name = models.CharField(max_length=128) def __str__(self): # __unicode__ on Python 2 return self.name class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership') def __str__(self): # __unicode__ on Python 2 return self.name class Membership(models.Model): person = models.ForeignKey(Person) group = models.ForeignKey(Group) date_joined = models.DateField() invite_reason = models.CharField(max_length=64)
members = models.ManyToManyField(Person, through='Membership')
group = models.ForeignKey(Group)
Отредактировано TitanFighter (Сен. 13, 2015 19:26:41)
Офлайн
Стоп, я сразу то не увидел, что одна из моделей у вас это through для М2М.
Вышесказанное отменяется.
Вероятно, это ограничение джанговского ОРМа, through модель должна быть описана в том же приложении, где она используется. Вам не надо все модели описывать в одном приложении, а только те которые вы используете в качестве промежуточных для привязки многие-ко-многим (в through).
Офлайн
С чем-то подобным сталкивался, навскидку может неточно скажу, но у меня работало и сработало.
Конечно это ограничение джанги, она пробует создавать модели, там ссылка на другую еще несозданную модель, все логично.
Если базы пустые и создаются с нуля, то
1) убрать в одной модели
showtime_place = models.ForeignKey('app_places.Place', verbose_name='Place')
2) Сделать makemigrations
3) migrate app_shows_and_times
4) migrate app_places
5) вернуть убранное поле
6) makemigrations и migrate app_shows_and_times
Возможно есть более изящное решение, но в доке джанго примерно такая же рекомендация
Там они еще предлагают потом squashmigrations сделать, чтобы свернуть миграции в одну, я не делал.
Полезно читнуть
А если данные в моделях уже есть, то там надо в сторону fakemigrations смотреть, увы точно не подскажу.
Офлайн
А может они просто не в той последовательности импортируются?
Логично было бы, если бы первой импортировалась модель Place, а потом Showtime.
TitanFighter, расставьте принты в классах, как оно у вас происходит?
Офлайн
nnmwareУже на этом шаге всплывает
1) убрать в одной модели
showtime_place = models.ForeignKey('app_places.Place', verbose_name='Place')
SystemCheckError: System check identified some issues: ERRORS: app_shows_and_times.Showtime: (fields.E336) The model is used as an intermediate model by 'app_places.Place.movie', but it does not have a foreign key to 'Place' or 'Show'.
movie = models.ManyToManyField('app_shows_and_times.Show', through='app_shows_and_times.Showtime')
FishHook
TitanFighter, расставьте принты в классах, как оно у вас происходит?
#settings PROJECT_APPS = [ 'app_places', 'app_shows_and_times', ] #принты Place Show Showtime
#settings PROJECT_APPS = [ 'app_shows_and_times', 'app_places', ] #принты Show Showtime Place
NameError: name 'Show' is not defined
movie = models.ManyToManyField('app_shows_and_times.Show', through='app_shows_and_times.Showtime')
Едит2:
7. Ок, таблица не создалась. Для эксперимента из п.1 оставляю только movie = models.ManyToManyField('app_shows_and_times.Show') и убираю through='app_shows_and_times.Showtime'
8. makemigrations app_places -> ok
9. migrate заканчивается ожидаемымВопрос этого Едита №2 - Таблицы нету, поля нового тоже никакого нету (я просмотрел), на что же тогда ругань Джанги?ValueError: Cannot alter field app_places.Place.movie into app_places.Place.movie - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields)
С поправкой на ночь и тугодумство пришел светлый вопрос - может в данном случае и не должно быть никакой новой таблицы, так как вместо сводной таблицы у нас ключи place_id и show_id указываются в полях showtime_place и showtime_show???class Showtime(models.Model): ##### showtime_place = models.ForeignKey('app_places.Place', verbose_name='Place') showtime_show = models.ForeignKey(Show, verbose_name='Show name')
movie = models.ManyToManyField('app_shows_and_times.Show', through='app_shows_and_times.Showtime')
movie = models.ManyToManyField('app_shows_and_times.Show')
ValueError: Cannot alter field app_places.Place.movie into app_places.Place.movie - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields)
В соответствии с Едит2 описанным выше - может и не должно быть никакой отдельной таблицы при использовании параметра through в поле many2many?
4) Я нагуглил, что с django.db.migrations.graph.CircularDependencyError были проблемы у разных людей в разное время на разных версиях Джанго, и девы фиксили их. Сейчас все работает из коробки в варианте, когда параметр through в many2many ссылается на модель в этом же приложении и нету никакий проблем с миграцией.
По идее, оно должно работать тогда и при ссылке на модель в другом приложении (т.е. без костылей в виде комментирования строки с полем many2many и параметром through + игранием в makemigrations)?
Похож ли этот случай на баг? Может постучаться к девам\создать тикет?
Отредактировано TitanFighter (Сен. 15, 2015 03:46:04)
Офлайн
Я тут больше ничего подсказать не могу, throught вообще не использовал никогда, не было надобности.
Может и бага, но как ее грамотно описать- хз.
Офлайн