Django фильтр в поле OneToOne с добавлением «_id» и сбоем - PullRequest
1 голос
/ 26 марта 2020

В моем приложении Django есть следующая модель:

class Provider(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True)
    company = models.ForeignKey(Company, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.user)

Примечание user - это OneToOneField для моей таблицы CustomUser, а также первичный ключ этой таблицы.

В views.py я пытаюсь запросить эту таблицу с помощью Provider.objects.filter(user=request.user) и получаю django.db.utils.OperationalError: (1054, "Unknown column 'appname_provider.user_id' in 'field list'"). Проверяя мою базу данных MySql, я вижу столбцы (user, company_id). Так почему Django добавляет «_id» к user при попытке фильтрации?

Моя модель CustomUser:

class CustomUser(AbstractUser):
    is_provider = models.BooleanField()
    is_admin = models.BooleanField()
    first_name = models.CharField(max_length=128)
    last_name = models.CharField(max_length=128)
    email = models.EmailField(unique=True)
    REQUIRED_FIELDS = ["is_provider", "email"]
    objects = CustomUserManager()

    def __str__(self):
        return str(self.username)

1 Ответ

0 голосов
/ 26 марта 2020

Вот как я решил эту проблему:

  1. Отмена всех миграций: rm -rf appname/migrations/0* appname/__pycache__ и mysql: DELETE FROM django_migrations;
  2. Удалите таблицу Provider в mysql: DROP TABLE appname_provider;
  3. Создайте заново таблицу Provider в mysql со столбцом user_id вместо user: CREATE TABLE appname_provider (user_id INT PRIMARY KEY, company_id INT);
  4. Сброс миграций для встроенных приложений: python manage.py migrate --fake
  5. Выполните миграции для этого приложения: python manage.py makemigrations appname
  6. Поддельный запуск миграций, так как все таблицы все еще находятся в базе данных: python manage.py migrate --fake
  7. Мне тогда нужно было сделать company_id внешний ключ, потому что я не сделал этого на шаге 3, поэтому в Provider я сделал company = models.IntegerField(), сделал и запустил миграцию, затем установил его обратно на company = models.ForeignKey(Company, on_delete=models.CASCADE), сделал и снова запустил миграции. Это немного странно, но без этого изменения взад и вперед Django не обнаружил, что нужно сделать company_id внешним ключом.

Теперь Provider содержит столбец user_id в базе данных вместо user, поэтому запрос работает! Обратите внимание, что при таком подходе вы теряете все данные в таблице Provider, но остальная часть базы данных сохраняется. Я получил некоторые шаги из этого ответа: { ссылка }.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...