Тестирование миграции данных ManyToMany в Django
Я пытался добавить поле в мои модели отношений ManyToMany в Django. Шаг за шагом я создал новую модель, применил makemigrations и migrate. Я проверил, что у меня есть новая таблица в моей базе данных postgresql.
Теперь, прежде чем добавить ключевое слово through в поле ManyToMany, я хочу написать функцию в файле миграции, которая будет копировать старые данные предыдущей таблицы ManyToMany в новую с дополнительным полем.
Я следовал решению, описанному здесь: Ошибка миграции Django :вы не можете изменить к или из полей M2M, или добавить или удалить через= на полях M2M
Я хочу протестировать функцию, которая будет переносить данные в тестовую функцию, но я не понимаю, как это сделать.
вот мой код:
обследование/модели:
class Survey(BaseModel):
name = models.CharField(max_length=256, help_text='Survey name')
user = models.ManyToManyField(User, blank=True, help_text='patient')
обследование/модели:
class SurveyStatus(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
survey = models.ForeignKey(Survey, on_delete=models.CASCADE)
survey_status = models.CharField(max_length=10,
blank=True,
null=True,
choices=STATUS_SURVEY_CHOICES,
)
Написанная мной функция, которая должна копировать данные из предыдущего M2M в новый, следующая:
def create_through_relations(apps, schema_editor):
Survey = apps.get_model('survey', 'Survey')
SurveyStatus = apps.get_model('survey', 'SurveyStatus')
for survey in Survey.objects.all():
for user in survey.user.all():
SurveyStatus(
user=user,
survey=survey,
survey_status='active'
).save()
- Я не понимаю, что такое apps? потому что оно не распознается python .
- Я не понимаю, зачем мне нужен schema_editor, потому что он не используется
- он не распознает мои модели Survey или SurveyStatus
когда я попытался запустить этот скрипт с
if __name__ == "__main__":
create_through_relations(survey)
У меня такая ошибка
NameError: имя 'survey' не определено
а если я попробую эту функцию
from django.apps import apps
def create_through_relations():
Survey = apps.get_model('survey', 'Survey')
SurveyStatus = apps.get_model('survey', 'SurveyStatus')
for survey in Survey.objects.all():
for user in survey.user.all():
SurveyStatus(
user=user,
survey=survey,
survey_status='active'
).save()
когда я попытался запустить этот скрипт с
if __name__ == "__main__":
create_through_relations()
У меня такая ошибка
django.core.exceptions.AppRegistryNotReady: Модели еще не загружены.
Если кто-то может помочь и объяснить мне, как решить. спасибо
Apps означает приложение django, оно происходит от from django.apps import apps
. Мы используем его, чтобы избежать ошибки redondant при вызове некоторых моделей. Проверьте это https://docs.djangoproject.com/fr/4.0/ref/applications/
1: Приложения представляют различные части вашего проекта (Django Apps)
2: На данном этапе он вам не нужен. В общем, он переводит модели в синтаксис SQL.
3: python manage.py <...> действительно загружает модели для выполнения. Ваш файл пытается получить доступ к данным, которые недоступны, вот так.
4: Переменная survey не может быть найдена в функции python's main, поскольку вы никогда не объявляли ее там. Вы могли бы вызвать ее внутри вашего проекта.
6: Вы можете тестировать вещи, создавая test.py (Django Tests)
7: Вам не нужно переносить данные в совершенно новую таблицу после изменения модели, достаточно расширить существующую и перенести изменения:
class BaseModel(models.Model):
created = models.DateTimeField('created', default=timezone.now)
changed = models.DateTimeField('changed', default=timezone.now, blank=True, null=True)
class Survey(BaseModel):
uuid = models.UUIDField(primary_key=False, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=256, help_text='Survey name')
description = models.TextField('description', blank=True)
status = models.BooleanField(default=False) # paused/ active
class SurveyQuestion(BaseModel):
survey = models.ForeignKey(Survey, related_name='survey', on_delete=models.CASCADE)
text = models.CharField(max_length=256)
# 1 -> Text, # Integer, # ChoiceField, etc.
requested_result = models.IntegerField(default=0)
class QuestionResult(BaseModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
question = models.ForeignKey(SurveyQuestion, related_name='survey_question', on_delete=models.CASCADE)
answer = models.CharField(default='', max_length=256)