Pull to refresh

Comments 15

Отличная статья, спасибо!

Скажите, а зачем два метода для перехватывания сигналов, если можно их объединить в один

И да, разумеется необходимо напомнить о существовании метода django.contrib.auth.get_user_model() который позволяет получить в любом месте модель, определенную в settings.py
Спасибо. Но я всего лишь переводчик в данном случае.
Я переадресовал Ваш вопрос и замечание автору. Как только он ответит, я напишу сюда)
> а зачем два метода для перехватывания сигналов, если можно их объединить в один

Автор пишет, что никогда не задумывался над этим, просто в таком виде изучил это в прошлом. И соглашается, что лучше это переписать:
@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    instance.profile.save()

> необходимо напомнить о существовании метода django.contrib.auth.get_user_model()

Тут автор, ссылаясь на последний абзац документации Django:
you should reference the User model with the AUTH_USER_MODEL setting in code that is executed at import time. get_user_model() only works once Django has imported all models.
пишет, что «Это означает, что для определения моделей, регистрации сигналов, создания миграций и т.д., get_user_model () не работает.»
В чём преимущество использования сигналов перед переопределением метода save? Можно ли как-нибудь в самом описании поля указать чтобы связная модель всегда создавалась?
> В чём преимущество использования сигналов перед переопределением метода save?

Если я правильно понял Ваш вопрос, то при переопределении метода save(), Вы будете править исходники Django, а при использовании сигналов — нет.

> Можно ли как-нибудь в самом описании поля указать чтобы связная модель всегда создавалась?

Вот тут в официальной документации прямо сказано, что нет, и предлагается использовать сигналы для этого.
they do not get auto created when a user is created, but a django.db.models.signals.post_save could be used to create or update related models as appropriate
Править исходники Django — да ни в жизнь, просто добавить метод в модель:
def save(self, *args, **kwargs):
    is_created = self.pk is None
    super(BaseModel, self).save(*args, **kwargs)
    if is_created:
        one_to_one_model.objects.create(<some params>)

ну, как-то так… Преимущество я вижу в том, что все манипуляции с зависимой моделью расположены внутри базовой, т.е. ближе к месту, где он реально используется.
На сколько я понимаю, у Вас в проекте может быть приложение (не Ваше, и не одно), которое вообще ничего не знает о Profile, но по каким-то причинам иногда создает/изменяет/удаляет User. Более того, у Вас может быть несколько Profile (например от разных приложений) — в каком из них Вы будете размещать Ваш метод?

Меня смущает Ваш комментарий. По-моему, базовой моделью является User, а (все) Profile – зависимые. Потому что User может существовать без Profile, но не наоборот.
По-моему, я начал Вас понимать… Да, если есть несколько приложений, которые добавляют свои атрибуты к некой базовой модели, то переопределять её save не вариант — тут уже сигналами придётся обходиться. Спасибо за пример.
Это плохой подход, проверять на наличие ключа.
У модели есть свойство, которое можно использовать.
```
def save(self, *args, **kwargs)
super(self.__class__, self).save(*args, **kwargs)
if self._state.adding is True:
one_to_one_model.objects.create()
```
Спасибо, не знал. Так гораздо лучше смотрится.
Спасибо за статью!

Прошу совета :)

Насчет «Расширение AbstractBaseUser» — как я понял вы это делали для использования email как логин.
Вопрос — почему вы предпочли это готовому решению
https://github.com/dabapps/django-email-as-username

(просто тоже делаю проект где email == username и интересно ваше мнение)
Ммм… Это перевод. Перед аппрувом подвергся редакторской правке, поэтому это стало не очень заметно (убрали вниз в ссылку в спойлере, в моей первоначальной редакции ссылка на оригинал была первым предложением).

Я сейчас делаю проект на Django, где хотел бы использовать, как и Вы, e-mail в качестве логина. При поиске решений наткнулся на статью, перевод которой решил сделать для Хабра.

Ссылку, которую Вы дали (спасибо! за неё, она мне не попадалась), я посмотрю в понедельник, т.к. сейчас в командировке и есть только мобильный интернет. И отвечу Вам сразу после этого.
Sign up to leave a comment.

Articles