(друзья, входящие и исходящие заявки)?
А то у меня дичь какая-то выходит
https://gitlab.com/-/snippets/2131066
Пользователь, который просматривает свой список друзей в таблице Friends может быть как отправителем (friend_from), так и получателем (friend_to), из-за этого приходится выполнять какие-то левые действия с полученными данными в цикле, чтобы фронт получил нужный юзернейм и прочие данные
Мб это как-то упростить можно?
(Ну и не обращайте внимания, что это не совсем джанга, мне главное принцип понять, каким образом это реализовать правильно)
заново, что за нах у тебя? что значит список моих друзей? что значат поля фром и ту? зачем получаются и те и другие? также есть у джанги ~Q() может у твоей ормки тоже
крч, просто кью которое выше написал проверь, если есть юзай и всё (ну или эксклуд)
> что значит список моих друзей? Имеется Пользователь А. У Пользователя А могут быть входящие заявки в друзья (Пользователь А получает заявки от других пользователей) У Пользователя А могут быть исходящие заявки в друзья (Пользователь А отправляет заявку/заявки другим пользователям/пользователю) > что значат поля фром и ту? Поля friend_from friend_to определяет направление заявки, *кто* и *кому" отправляет заявку, соответственно определяет исходящий/входящий список заявок для отображения на фронте > зачем получаются и те и другие? Потому что Пользователь А может быть как в поле friend_from, так и в поле friend_to в зависимости от того, отправлял ли Пользователь А сам заявку или принимал чью-то чужую, именно поэтому фильтрация идёт сразу по двум полям (через тот самый Q) Q там есть (видимо сниппет даже не открывался). В этом и беда, что я своей глупой головой не соображу как верно составить запрос, чтобы он: 1. Вернул мне список друзей, основанный на фильтрации по полю friend_from friend_to в зависимости от направления движения (см. скриншот, у Пользователя А три друга, но из-за разного направления заявок я вынужден проверять самого Пользователя А по двум полям сразу) 2. Унифицировал название полей до username, вместо friend_from__username Там орм очень похожа на джанго, поэтому если бы мне скинули пример реализации, я бы мог легко это адаптировать под себя
Кое-как это было сделано через цикл, но это выглядит так, словно я вместо цемента кирпичную кладку делаю с помощью говна. Вроде та же субстанция, кирпичи липнут, но по сути то ерунда полная выходит)
ты наверное не заметил, но кью который я указал имеет ~ 2. также, ты можешь попробовать юзнуть эксклуд перед твоим фильтром
как-то так .filter( Q(friend_from__username=username_or_email), ~Q(friend_to__username=username_or_email) | Q(friend_to__username=username_or_email), ~Q(friend_from__username=username_or_email) ) естественно вместо юзернеймов где ~ ставишь "текущего" юзера (того чьих друзей ищешь) не, юзай как написал
Звучит как не очень удачная архитектура
Friend.filter(Q(Q(friend_from__username=username) & ~Q(friend_to__username=username)) | Q(Q(friend_to__username=username) | ~Q(friend_from__username=username))) Вышло что-то такое. Правда, это возвращает QuerySet с .friend_from .friend_to, то есть всё равно приходится дополнительно выполнять некоторые действия, чтобы в список друзей не попал пользователь, который этот самый список и просматривает # username - текущий пользователь, который находится на сайте и просматривает собственный список друзей for f in friends: if username != f.friend_from: friends.append(...) if username != f.friend_to: friends.append(...)
Вот поэтому и хотелось бы глянуть на удачные)
может быть m2m self связь через through таблицу, с дополнительным bolean полем - принята ли заявка?
Сейчас попробую, мб соображу чего)
может я тебя не понимаю, но у тебя есть записи в которых и фром и ту одновременно указывают на одного и того же? можешь показать случай где юзер получил список в котором он друг самого себя?
Не совсем так Пользователь, который просматривает свой список, может быть либо в одном поле, либо в другом, но не в двух сразу То есть я на фронт без обработки могу вернуть оба поля (фром, ту), но нужно одно поле и только то, которым пользователь не является Т.е. на основе этого скрина получается, что итоговый 'username', возвращаемый на фронт, определяется по полям friend_from, friend_to, friend_to: friends { {'username': 'One'}, {'username': 'Two'}, {'username': 'Three'} } Т.е. мне приходится дополнительно проверять from, to, чтобы в словарь не добавить самого себя: # если текущий пользователь НЕ является пользователем в поле from, то добавляем пользователя из f.friend_from в итоговый список друзей if username != f.friend_from: friends.append({'username': f.friend_from}) # аналогично с from_toi В общем я сейчас попробую через m2m сделать, авось получится)
теперь, по-моему, дошло. твой селект должен быть таким select case when from = username then to else from end as username from friends where from = username or to = username в орм наверное так annotate(username=Case(When(friend_from__username=username, then='friend_to__username'), When(friend_to__username=username, then='friend_from__username')) с твоим изначальным фильтром
Не соображу. Прям совсем не соображу https://gitlab.com/-/snippets/2131150 Я хоть в правильном направлении то иду?
а то что я те скидывал с предыдущим ты не проверил?
Неа Меня разочаровало, что инструмент, которым я пользовался, содержит проблему, которая висит в issues больше месяца (миграции ломаются, если добавлять m2m поля) и поэтому решил упороться в алхимию. Как разберусь, буду уже пробовать всякое)
так стоп алхимия не поддерживает асинсио, а у тебя там было асинк или уже поддерживает?
Всё там поддерживается же, и синхронные и асинхронные До этого я пользовался tortoise orm, там это сразу из коробки идёт без каких-либо настроек, типо пихай async await и готово, а в алхимии мудрить надо немного. Ну если я правильно понял всё Какие-то сессии, движки, сессионмакеры, в общем чуть посложнее, поэтому я его изначально отложил. Ну и к тому же модельки в tortoise сильно похожи на джанговские и миграционный инструмент очень простой - migrate/upgrade/downgrade и всё. Если бы не эта беда с m2m, я бы даже не подумал с него съезжать
увидел, там экстеншн под асинсио, также скорее всего тебе понадобится алембик или что-нибудь похожее
Да да, без алембика никуда Собственно, по этим двум критериям инструмент и выбирался, чтобы можно было в файле определить модель и на основе этой модели создать автоматически таблицу (или обновить/удалить уже существующую таблицы/поля/что-угодно)
В общем-то всё это переписалось вот так, под m2m https://gitlab.com/-/snippets/2131366 По ощущениям архитектура теперь кажется ещё более сложной (мб из отсутствия опыта работы с m2m связями вообще), но это работает. Да и времени прилично убил на освоении нового инструмента, поэтому так и оставлю. А то это переходит в разряд "целый день думать над тем как называть переменную". Типо я же получаю нужные данные? Получаю? Ну и вот, чего ещё надо
светлая тема🤭
Очень больно глазам прыгать в белый веб из чёрной ide, поэтому стараюсь везде держать светлые темы
да видел сегодня уже где-то этот афоризм
получается логичненько🧐
Это не то что афоризм, это личные наблюдения Это прям реально по глазам бьёт. Конечно можно всяких расширений для инвертирования цвета на браузер поставить, но это какое-то такое В общем нет ничего плохого в светлой теме, дело вкуса Я вот не понимаю такие темы как solarized, когда в глаза идёт дикая желтизна
вроде бы полезно тёплые цвета
Обсуждают сегодня