Я пытаюсь сохранить экземпляр модели 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?






Ваш 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 имели смысл.
Я не понимаю проблемы, но строки базы данных связаны с использованием первичных ключей, а в вашем примере ключами являются столбцы id. Если вы знаете id из Item, которыми владеет UserProfile, вы можете просто использовать цикл for, чтобы связать эти Item с этим UserProfile.
Вы правы, я полагаю, я просто буду использовать цикл for для группировки элементов и не усложнять ситуацию еще больше. Спасибо!
И наконец, хотя в моем случае это сработало, меня беспокоит то, что это решение не кажется масштабируемым. Если я не ошибаюсь, не приведет ли такое связывание items к users к произвольному увеличению времени отклика useritems в зависимости от number of users? Возможно, Django просто не очень подходит для подобных задач, но мне интересно, есть ли для этого более масштабируемое решение.
Опять же непонятно, что вас беспокоит. Получение любых произвольных UserItem зависит только от ожидаемого количества Item. Или вас беспокоит получение каждого Item, обновление user внешнего ключа и его сохранение?
Извиняюсь, если быть более конкретным, в моем бэкэнде есть представление под названием get_items, которому передается user в качестве аргумента. Здесь я получаю список этих useritem с помощью строки data = list(Item.objects.filter(user_profile=user_profile).values()). Мой вопрос: не потребует ли это, чтобы база данных «фильтровала» все элементы от каждого пользователя каждый раз, когда запрашивается один useritem, тем самым увеличивая RRT для каждого запроса по мере накопления новых item? Возможно, я неправильно понимаю, как SQL обрабатывает запросы такого типа? Я новичок, поэтому прошу прощения за путаницу.
RTT*, время прохождения ответа.
Поскольку Django автоматически проиндексирует столбец FK (т. е. Item.user_profile), механизму базы данных не придется выполнять полное сканирование таблицы, и влияние будет минимальным. Другими словами, движок знает, где в таблице находится каждый Item, связанный с данным User, поскольку для этой конкретной цели он хранит отдельную хеш-карту (т. е. индекс). См. postgresql.org/docs/current/indexes.html. В общем, не следует пытаться микрооптимизировать структуру базы данных, если только вы не имеете дело с миллионами записей.
Понятно. Я ценю ваше объяснение и помощь с исходной проблемой!
Спасибо, я не знал, что ForeignKey работает таким образом. Однако, оглядываясь назад, я понимаю, что эти отношения не полностью достигают того, что я ищу. Теперь у меня есть ForeignKey, в котором «многие
Itemсопоставлены с однимUserProfile», однако эти элементы хранятся индивидуально в моделиItemsв моей базе данных. Для этого мне нужно перебрать каждый элемент, чтобы определить, какие из них принадлежат каждому пользователю. Будет ли вместо этого существовать способ предоставить каждому пользователю массив элементов вместо того, чтобы назначать пользователю каждый отдельный элемент?