Django: как создать уникальный экземпляр одной модели как поле в другой модели

Я пытаюсь сохранить экземпляр модели Item как поле в моей модели пользователей, используя ForeignKey следующим образом:

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    username = models.CharField(max_length=255)
    items = models.ForeignKey('Item', on_delete=models.CASCADE)

    def __str__(self):
        return self.username
    
class Item(models.Model):
    stats = models.JSONField(null=True)
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

Однако в настоящее время кажется, что каждый новый пользователь использует один и тот же список элементов, когда я проверяю свою панель администратора Django (по сути, в настоящее время существует только один экземпляр Item, который доступен каждому пользователю). Вместо этого моя цель состоит в том, чтобы у каждого пользователя был свой собственный список элементов, не связанный со списком других пользователей. Есть ли способ сделать так, чтобы у каждого пользователя в учетной записи было поле, которое является уникальным экземпляром модели Items?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш ForeignKey расположен не в том направлении. Внешний ключ — это отношение «многие к одному», поэтому существующая структура модели подразумевает «многие UserProfile к одному Item».

Это должно быть в модели Item:

class Item(models.Model):
    user_profile = models.ForeignKey(
        UserProfile, on_delete=models.CASCADE, related_name = "items"
    )
    ...

Имя поля ForeignKey всегда должно быть в единственном числе, а related_name (т. е. обратное отношение) должно быть во множественном числе, чтобы и my_user_profile.items, и my_item.user_profile имели смысл.

Спасибо, я не знал, что ForeignKey работает таким образом. Однако, оглядываясь назад, я понимаю, что эти отношения не полностью достигают того, что я ищу. Теперь у меня есть ForeignKey, в котором «многие Item сопоставлены с одним UserProfile», однако эти элементы хранятся индивидуально в модели Items в моей базе данных. Для этого мне нужно перебрать каждый элемент, чтобы определить, какие из них принадлежат каждому пользователю. Будет ли вместо этого существовать способ предоставить каждому пользователю массив элементов вместо того, чтобы назначать пользователю каждый отдельный элемент?

fault 17.05.2024 04:27

Я не понимаю проблемы, но строки базы данных связаны с использованием первичных ключей, а в вашем примере ключами являются столбцы id. Если вы знаете id из Item, которыми владеет UserProfile, вы можете просто использовать цикл for, чтобы связать эти Item с этим UserProfile.

Selcuk 17.05.2024 05:34

Вы правы, я полагаю, я просто буду использовать цикл for для группировки элементов и не усложнять ситуацию еще больше. Спасибо!

fault 17.05.2024 05:41

И наконец, хотя в моем случае это сработало, меня беспокоит то, что это решение не кажется масштабируемым. Если я не ошибаюсь, не приведет ли такое связывание items к users к произвольному увеличению времени отклика useritems в зависимости от number of users? Возможно, Django просто не очень подходит для подобных задач, но мне интересно, есть ли для этого более масштабируемое решение.

fault 19.05.2024 02:56

Опять же непонятно, что вас беспокоит. Получение любых произвольных UserItem зависит только от ожидаемого количества Item. Или вас беспокоит получение каждого Item, обновление user внешнего ключа и его сохранение?

Selcuk 19.05.2024 04:44

Извиняюсь, если быть более конкретным, в моем бэкэнде есть представление под названием get_items, которому передается user в качестве аргумента. Здесь я получаю список этих useritem с помощью строки data = list(Item.objects.filter(user_profile=user_profile).values()‌​). Мой вопрос: не потребует ли это, чтобы база данных «фильтровала» все элементы от каждого пользователя каждый раз, когда запрашивается один useritem, тем самым увеличивая RRT для каждого запроса по мере накопления новых item? Возможно, я неправильно понимаю, как SQL обрабатывает запросы такого типа? Я новичок, поэтому прошу прощения за путаницу.

fault 19.05.2024 05:56

RTT*, время прохождения ответа.

fault 19.05.2024 06:06

Поскольку Django автоматически проиндексирует столбец FK (т. е. Item.user_profile), механизму базы данных не придется выполнять полное сканирование таблицы, и влияние будет минимальным. Другими словами, движок знает, где в таблице находится каждый Item, связанный с данным User, поскольку для этой конкретной цели он хранит отдельную хеш-карту (т. е. индекс). См. postgresql.org/docs/current/indexes.html. В общем, не следует пытаться микрооптимизировать структуру базы данных, если только вы не имеете дело с миллионами записей.

Selcuk 19.05.2024 06:40

Понятно. Я ценю ваше объяснение и помощь с исходной проблемой!

fault 19.05.2024 07:58

Другие вопросы по теме