Все вопросы по Django
1035
21
Добрый вечер
Надоело плодить темы с разными вопросам, решил для себя создать 1 темку, которую буду апать
____________________________________________________________________________________________
Не знаю, как решить вот эту фигню
Спойлер:У меня получается очень много SQL запросов (чем больше категорий я добавляю -> тем больше запросов получаю)
Как правильно написать запрос, чтобы БД отдавал кверисет с моим условием?
Вот модели
Спойлер: "News"class News(models.Model): title = models.CharField('Наименование', max_length=150) content = models.TextField('Контент', blank=True) created_at = models.DateTimeField('Дата публикации', auto_now_add=True) updated_at = models.DateTimeField('Обновлено', auto_now=True) photo = models.ImageField('Фото', upload_to='photos/%Y/%m/%d/', blank=True) is_published = models.BooleanField('Опубликовано', default=True) category = models.ForeignKey('Category', on_delete=models.PROTECT, null=True, verbose_name='Категория') views = models.IntegerField('Количество просмотров', default=0)Спойлер: "Category"class Category(models.Model): title = models.CharField('Наименование категории', max_length=150, db_index=True)
Дринбибиска сказал(а):↑получается очень много SQL запросов
Нажмите, чтобы раскрыть...
saw_tooth сказал(а):↑Нажмите, чтобы раскрыть...Да на самом SQL может я и сам смогу написать(не с 1 раза, но уверен что напишу)
Мне не понятно как это сделать с помощью ORM джанги
Дринбибиска сказал(а):↑Мне не понятно как это сделать с помощью ORM джанги
Нажмите, чтобы раскрыть...
Stupid_Squirel сказал(а):↑моё сообщение на премодерацию ушло...
крч category.news_set.filter(is_published=True). Если я правильно понял, что тебе нужно. А вообще ссылки тебе уже кинули там всё естьНажмите, чтобы раскрыть...Ну я так и написал в цикле -> стали появляться запросы каждую итерацию
Они хоть и маленькие (~0.06 ms) , но их кол-во зависит от кол-ва категорий
Дринбибиска сказал(а):↑Ну я так и написал в цикле -> стали появляться запросы каждую итерацию
Они хоть и маленькие (~0.06 ms) , но их кол-во зависит от кол-ва категорий
Нажмите, чтобы раскрыть...тебе не нужен цикл для этого. Фильтр вернет тебе queryset в котором будут категории по твоему условию. Выведи на экран/почитай про filter
Stupid_Squirel сказал(а):↑тебе не нужен цикл для этого. Фильтр вернет тебе queryset в котором будут категории по твоему условию. Выведи на экран/почитай про filter
Нажмите, чтобы раскрыть...Но я ведь могу фильтровать категорию только по ее полям
Category.objects.filter(title__cointains='test') и получу все категории у которых есть в названии строка test
Могу вот так обратиться Category.objects.get(pk=4).news_set.filter(is_published=True)
Но мне нужно использовать .all() , а после all я фильтровать не могу, как написал выше
Возможно annotate или prefetch_related или еще что-то , я еще не разобрался
Дринбибиска сказал(а):↑Но я ведь могу фильтровать категорию только по ее полям
Category.objects.filter(title__cointains='test') и получу все категории у которых есть в названии строка test
Могу вот так обратиться Category.objects.get(pk=4).news_set.filter(is_published=True)
Но мне нужно использовать .all() , а после all я фильтровать не могу, как написал выше
Возможно annotate или prefetch_related или еще что-то , я еще не разобралсяНажмите, чтобы раскрыть...открой документацию и посмотри сам, ты по-моему не особо вообще понимаешь, что делаешь... Учитывая что тут уже есть 2 ответа
Дринбибиска сказал(а):↑Но я ведь могу фильтровать категорию только по ее полям
Category.objects.filter(title__cointains='test') и получу все категории у которых есть в названии строка test
Могу вот так обратиться Category.objects.get(pk=4).news_set.filter(is_published=True)
Но мне нужно использовать .all() , а после all я фильтровать не могу, как написал выше
Возможно annotate или prefetch_related или еще что-то , я еще не разобралсяНажмите, чтобы раскрыть...а, походу наконец дошло что ты сделать хочешь
Stupid_Squirel сказал(а):↑открой документацию и посмотри сам, ты по-моему не особо вообще понимаешь, что делаешь... Учитывая что тут уже есть 2 ответа
Нажмите, чтобы раскрыть...Я реально не понимаю, что-то или это троллинг?
Или ты не понял что я хочу сделать?
Я просто уже кучу вариантов перепробовал в шеле -> либо ошибки, либо не тот результат
Я хочу что то типо такого (возможно тут будут ошибки и запрос будет не верный)
SELECT title FROM Category catJOIN News ON news.category=cat.id WHERE news.is_published=True
Stupid_Squirel сказал(а):↑Category.objects.filter(news_set__is_published=True) попробуй так
Нажмите, чтобы раскрыть...Cannot resolve keyword 'news_set' into field. Choices are: id, news, title
upd.
categories = Category.objects.filter(news__is_published=True).distinct()вот так получил нужный результат
А почему в данном случае news , а не news_set PS: я такой запрос сам уже писал, только ошибку прочитал только что
Дринбибиска сказал(а):↑Я хочу что то типо такого (возможно тут будут ошибки и запрос будет не верный)
SELECT title FROM Category catJOIN News ON news.category=cat.id WHERE news.is_published=True
Cannot resolve keyword 'news_set' into field. Choices are: id, news, title
upd.
categories = Category.objects.filter(news__is_published=True).distinct()вот так получил нужный результат
Нажмите, чтобы раскрыть...да я случайно `_set` приписал, отредачил уже
F5
Доброй ночи рамисты
Насколько правильно я реализовал аутентификацию по логину либо емейлу?
https://github.com/BeginnerA234/Django-Custom-User
UPD: Плохое решение от меня не учитывать регистр при просмотре логина т.к в бд можно сохранить User и uSer -> при проверке вылетает ошибка
Дринбибиска сказал(а):↑Насколько правильно я реализовал аутентификацию по логину либо емейлу?
Нажмите, чтобы раскрыть...Ты её вообще не реализовал.
Бэкенд аутентификации должен содержать два метода: authenticate() и get_user(). У тебя есть кривой authenticate() и отсутствует get_user().Комментарий к классу EmailAndLoginAuthBackend совершенно не соответствует сути, я бы за подобное выпорол джуна.
oct2048 сказал(а):↑Ты её вообще не реализовал.
Бэкенд аутентификации должен содержать два метода: authenticate() и get_user(). У тебя есть кривой authenticate() и отсутствует get_user().Комментарий к классу EmailAndLoginAuthBackend совершенно не соответствует сути, я бы за подобное выпорол джуна.
Нажмите, чтобы раскрыть...Окей, возможно я не правильно выразился
Изменил правило аутентификации
Метод get_user наследуется ведь
И в чем кривость authenticate? Что исправить ?
Комментарий считаю верным. Почему он не правильный?
Меня на локалке пускает в админку и по емейлу и по логину. Прочих юзеров не пускает
oct2048 сказал(а):↑Ты её вообще не реализовал.
Бэкенд аутентификации должен содержать два метода: authenticate() и get_user(). У тебя есть кривой authenticate() и отсутствует get_user().Комментарий к классу EmailAndLoginAuthBackend совершенно не соответствует сути, я бы за подобное выпорол джуна.
Нажмите, чтобы раскрыть...козел а нужно попробовать нормально объяснить
Дринбибиска сказал(а):↑Метод get_user наследуется ведь
Нажмите, чтобы раскрыть...Все верно, не обратил внимание, что ты наследуешься от ModelBackend, я бы сделал обычный object.
Дринбибиска сказал(а):↑И в чем кривость authenticate? Что исправить ?
Нажмите, чтобы раскрыть...У тебя три ветки логики:
1. Пользователь найден, пароль верен -> return user
по этой ветке вопросов нет
2. Пользователь найден, пароль не верен -> обработчика нет
как минимум тут надо делать return None
3. Пользователь не найден -> делаешь не пойми что
как минимум нужен return None или return user, если ты хотел его создать.
Попробуй такой вариант:
#settings.py
AUTHENTICATION_BACKENDS = <
'django.contrib.auth.backends.ModelBackend', 'account.authentication.EmailAuthBackend',]
#auth.py
class EmailAuthBackend(object):
"""Выполняет аутентификацию пользователя по e-mail.
"""
def authenticate(self, request, username=None, password=None):
try: user = User.objects.get(email=username) if user.check_password(password): return user return None except User.DoesNotExist: return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id) except User.DoesNotExist: return None
Дринбибиска сказал(а):↑Комментарий считаю верным. Почему он не правильный?
Нажмите, чтобы раскрыть...Ответь себе на вопросы:
1. Для кого пишут описание классов?
2. Для чего пишут?
3. Соответствует ли написанное тобой описание первым двум вопросам?
Больше читай чужой код, желательно профессиональный и обращай внимание на то, как там оформляют код.
Еще тебе на подумать.
В стандартной модели User, поле email не уникально, т.е. может быть несколько юзеров с одинаковыми емейлами. Более того, могут быть юзеры у которых в username написан емейл.
Исходя из этого
user = CustomUser.objects.get(Q(username=username) | Q(email=username))
не стабильно. Нужен обработчик исключения MultipleObjectsReturned
oct2048 сказал(а):↑Все верно, не обратил внимание, что ты наследуешься от ModelBackend, я бы сделал обычный object.
У тебя три ветки логики:
1. Пользователь найден, пароль верен -> return user
по этой ветке вопросов нет
2. Пользователь найден, пароль не верен -> обработчика нет
как минимум тут надо делать return None
3. Пользователь не найден -> делаешь не пойми что
как минимум нужен return None или return user, если ты хотел его создать.
Попробуй такой вариант:
#settings.py
AUTHENTICATION_BACKENDS = < 'django.contrib.auth.backends.ModelBackend', 'account.authentication.EmailAuthBackend',]
#auth.py
class EmailAuthBackend(object):
"""Выполняет аутентификацию пользователя по e-mail.
"""
def authenticate(self, request, username=None, password=None):
try: user = User.objects.get(email=username) if user.check_password(password): return user return None except User.DoesNotExist: return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id) except User.DoesNotExist: return None
Ответь себе на вопросы:
1. Для кого пишут описание классов?
2. Для чего пишут?
3. Соответствует ли написанное тобой описание первым двум вопросам?
Больше читай чужой код, желательно профессиональный и обращай внимание на то, как там оформляют код.
Еще тебе на подумать.
В стандартной модели User, поле email не уникально, т.е. может быть несколько юзеров с одинаковыми емейлами. Более того, могут быть юзеры у которых в username написан емейл.
Исходя из этого
user = CustomUser.objects.get(Q(username=username) | Q(email=username))
не стабильно. Нужен обработчик исключения MultipleObjectsReturned
Нажмите, чтобы раскрыть...Спасибо за развернутый ответ
Завтра буду все пробовать
Комментарии ещё учусь писать
А поводу email я его сделал в модели уникальным
P.s: только эта уникальность будет скорее всего криво работать т.к уникальным считается любое изменение регистра, а не сам адресс.
Нужно email в нижнем регистре записывать
Дринбибиска сказал(а):↑А поводу email я его сделал в модели уникальным
Нажмите, чтобы раскрыть...Этого не достаточно. То что ты описал у себя в модели, приведет к созданию констреинта в базе данных, но то как будет обрабатываться этот констреинт зависит от конкретного экземпляра СУБД (там есть опция регистрозависимости). Нужно чекать этот момент.
Дринбибиска сказал(а):↑эта уникальность будет скорее всего криво работать т.к уникальным считается любое изменение регистра
Нажмите, чтобы раскрыть...Это зависит от опции СУБД.
Дринбибиска сказал(а):↑Нужно email в нижнем регистре записывать
Нажмите, чтобы раскрыть...Да, но тут тоже не всё однозначно. Если есть варианты редактирования записи в БД не из твоего приложения (например админ может править таблицы напрямую через инструменты СУБД), то нужно приводить в нижний регистр на стороне СУБД, например делать калькулейтед поле или триггер.
Тема закрыта
-
ЗаголовокОтветов ПросмотровПоследнее сообщение
-
Сообщений:2
Просмотров:2
-
Сообщений:6
Просмотров:11
-
Сообщений:8
Просмотров:10
-
doleg64 26 Apr 2024 в 11:58Сообщений: 2 26 Apr 2024 в 11:58
Сообщений:2
Просмотров:4
-
Сообщений:28
Просмотров:38