#python #django #django-models #orm #django-queryset
#питон #джанго #джанго-модели #орм #django-набор запросов
Вопрос:
Я пытаюсь показать предложения по профилям пользователей для пользователя LoggedIn на основе тегов, которым он/она следует, В моем случае мне нужно перейти в класс User_Interests_Tag, чтобы получить все теги, затем посетить класс Post_Tag, чтобы получить все сообщения для каждого тега(цикл), как только у меня будут все идентификаторы, посетите класс Post, чтобы получить каждого уникального пользователя и добавить его в профиль(список) и использовал paginator для ограничения профилей, отправленных клиенту. Как я могу добиться этого без использования циклов for для увеличения общей эффективности и времени отклика от сервера?
Модели:
class User_Interests_Tag(models.Model): # User Suggestions Tag to User link id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True) user = models.ForeignKey(User, null=False, on_delete=models.CASCADE) tag = models.ForeignKey(Tag, null=False, on_delete=models.CASCADE) priority = models.FloatField(default=0.0) class Post_Tag(models.Model): # Post Media Link id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True) post = models.ForeignKey(Post, on_delete=models.CASCADE) tag = models.ForeignKey(Tag, on_delete=models.CASCADE) class Post(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True) user = models.ForeignKey(User, on_delete=models.CASCADE, null=True) title= models.CharField(max_length=500, default="unknown", null=True) description = models.CharField(max_length=512 , null = True) date_posted = models.DateTimeField(auto_now_add=True)
вот фрагмент того, чего я хочу достичь :
#looping through each tag for user_interests_tag in user_interests_tags: #user_post_tags = Post_Tag.objects.in_bulk(user_interests_tags) (used bulk but no luck) user_post_tags.extend(list(Post_Tag.objects.filter(tag_id = user_interests_tag).values_list('post_id', flat=True))) profiles = [] #looping through each tag id for user_post_tag in user_post_tags: #getting the user from post class user = Post.objects.get(id = user_post_tag) #checking if already follows and if already their in user profiles array if user not in profiles and not User_Follow.objects.filter( owner_id = user_id.id, user_id = user.user_id): profiles.append(user) #paginating 6 per request paginator = Paginator(profiles,6) limited_profiles = paginator.page(page) return limited_profiles
Любые зацепки очень ценю, заранее спасибо 🙂
Комментарии:
1. Можете ли вы поделиться своими моделями?
2. Конечно , пожалуйста, проверьте выше, я только что отредактировал его с моделями!
Ответ №1:
Вы могли бы сделать что-то вроде этого:
posts = Post.objects.filter( Q(post_tag_set__tag__in=user_interests_tags) amp; ~Q(user__in=User_Follow.objects.filter(owner_id=user_id.id).values('user')) ).distinct() paginator = Paginator(posts, 6) limited_profiles = paginator.page(page) return limited_profiles
Чтобы подробнее остановиться на этом:
Q(post_tag_set__tag__in=user_interests_tags)
Выше будет отфильтровано все Post
s, у которых есть Post_Tag
s с Tag
совпадением s user_interests_tags
.
~Q(user__in=User_Follow.objects.filter(owner_id=user_id.id).values('user'))
Вышеизложенное также будет фильтровать Post
s с помощью a user
, который не соответствует ни User_Follow
одному объекту на основе фильтра идентификатора владельца, который у вас есть в данный момент.
Комментарии:
1. Эй , спасибо за четкое объяснение, в этой строке Q(post_tag_set__tag__in=user_interests_tags) я получаю сообщение об ошибке : Не удается разрешить ключевое слово «post_tag_set» в поле.
2. Это утверждение на самом деле отфильтровывает идентификаторы тегов, но мне нужно, чтобы идентификаторы сообщений отфильтровывались из модели сообщений, пожалуйста, дайте мне подсказку о том, как выбрать значение идентификатора записи в вышеупомянутом заявлении. Спасибо 🙂
3. Эй @BrianDestura приведенный ниже код работает для меня и значительно сократил время отклика для больших записей, пожалуйста, дайте мне знать, если у вас есть какой-либо другой способ оптимизировать его еще больше. с нетерпением ждем вашего ответа!
posts = Post.objects.filter(Q(id__in = Post_Tag.objects.filter(Q(tag__in = User_Interests_Tag.objects.filter(user_id = user_id.id).values_list('tag_id', flat=True))).values_list('post_id', flat=True) ) amp; ~Q(user__in=User_Follow.objects.filter(owner_id=user_id.id).values('user'))).distinct().order_by('-id')
4. О, как здорово слышать, что это улучшилось! Вы можете
post_tag_set
заменить фактическимrelated_name
, который вы используете (обратный способ доступа от поста к тегу поста) (может быть, просто попробуйтеpost_tag
). По сути, ваш текущий код делает то же самое с ответом, который я опубликовал.5. Конечно, @Брайан, я попробую , большое вам спасибо, я действительно ценю ваше время и надеюсь, что у вас будет отличный день, сэр 🙂