В django появилась возможность использования своей модели вместо contrib.auth.models.User

    image

    Через шесть лет после появления тикета с предложением возможности использования своей модели вместо штатной django.contrib.auth.models.User и тысяч постов с идеями использования дополнительной модели профилей случилось чудо: https://github.com/django/django/commit/70a0de37d132e5f1514fb939875f69649f103124



    Теперь модель пользователя указывается в настройках проекта:

    AUTH_USER_MODEL = 'auth.User'


    А для создания ForeignKey к модели пользователя предлагают использовать следующий способ:

    user = models.ForeignKey(settings.AUTH_USER_MODEL)


    При этом отдельно рекомендуется обдумать необходимость хранения всей информации пользователя, не относящейся к авторизации, в одной модели. Возможно, лучшим способом хранения таких данных будет старый добрый способ с дополнительными моделями; это позволит каждому приложению иметь свою информацию о пользователе без риска конфликтов с другими приложениями.

    Остальная документация по новой функциональности уже есть на сайте: docs.djangoproject.com/en/dev/topics/auth/#customizing-the-user-model

    Те, кому не терпится опробовать долгожданную фичу в действии, уже могут использовать trunk репозитория, любителям стабильности же придется ждать выхода django 1.5.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 71

      +4
      Супермен, ты всё-таки существуешь!

      Непонятно только, что теперь делать с кучей старых но вполне качественных приложений. Некоторые из них уже и не поддерживаются, но вполне себе работают.
        +1
        Не обновлять Django до версии в которой уберут get_profile()?
          +1
          По-моему, get_profile() мало где используется ввиду своей ущербности. Да и не о нём речь, а о приложениях, в которых захардкожена ссылка на User:

          from django.contrib.auth.models import User
          
          class Blog(models.Model):
              user = models.ForeignKey(User)
          


          А ведь есть ещё и всякие django-registartion и аналоги, где создаются объекты именно auth.User. Существенная часть приложений, возможно даже хороших, станет несовместимой.
            +1
            Ну так эту модель, судя по документации, вроде, не убирают? Проблемы будут при совместном использовании и того и того способа, это да, в доке так и сказано.
              0
              В этом весь трагизм ситуации и заключается: появился чудесный механизм, а использовать его совместно с другими батарейками не получится.
                0
                Использовать с батарейками можно будет когда батарейки подтянутся. Пока же ещё даже релиза не было. У авторов батареек ещё есть время поправить, что надо. Тем более, это не так уж и сложно.
                  0
                  Некоторые из них уже и не поддерживаются, но вполне себе работают.

                    +3
                    Если они такие полезные, то нично не мешает их поправить. Или форкнуть.

                    Заменить User на settings.AUTH_USER_MODEL или на get_auth_model() это не такое уж и большое дело.
                      0
                      Форкнуть их, конечно, можно. Скорее всего, так и придётся делать. Но осадочек всё-таки останется: больше не выйдет написать, например,

                      $ pip install django-registration

                      потому что в PYPI лежит устаревший модуль. Всем придётся делать что-то типа такого.

                      $ pip install -e git+github.com/fork-author/django-registration-fork#egg=django-registration

                      Единого реестра «официальных» форков, разумеется нет. Откуда же разработчикам знать, откуда брать то или иное приложение? Каждый будет форкать, что только будет увеличивать энтропию вселенной :)
                        0
                        назови его django-registration-s и добавь в PyPI
                          0
                          Так и будут делать, скорее всего. Что, впрочем, не отменяет ремарки про увеличение энтропии вселенной.
                            0
                            а как предлагаешь надо было сделать это?
                              +1
                              Я вижу только один выход: смириться. Ну, либо писать забившим мэйнтейнерам, чтобы уступили штурвал тем, кто хочет заниматься поддержкой. Хотя это, конечно, утопия.
                                0
                                А pull requests отменили?

                                Если разработчик живой (извините за прямоту), то он всегда может принять Ваши изменения в проект, если опишите адекватно что и зачем меняли
                                  0
                                  А если не живой? Если ушёл в другие сферы деятельности или просто потерял интерес к проекту? Или доступ?

                                  Я уже и не говорю о том, что многие разработчики популярных и развивающихся продуктов откровенно игнорируют пулл риквесты, за которое очень активно голосует сообщество.
              0
              Кроме объявления get_profile устаревшей других изменений ломающих совместимость нет.

              Ещё возможно, сломана локализация админки (мне так показалось при просмотре коммита).
            0
            Как я понял в джанго 1.5 профиле уже не нужны. Это говорят сами разработчики и они убрали AUTH_PROFILE_MODULE
              0
              Ничего не убрали. Просто объявили устаревшим. Использовать по-старому всё ещё можно.
          +2
          Это круто, конечно. Осталось только всё переписать :)
            +2
            Жили же как-то с AUTHENTICATION_BACKENDS и наследованием своих пользовательских моделей от базовой User. Сторонние приложения получают нашу модель, но работают с ней как со стандартной и не жалуются (ибо унаследована именно от неё). Так что ничего революционного я тут особо не вижу, похожий функционал можно получить и с текущей версией.
              +1
              Ключевое слово — «как-то». Да, оно действительно работало, но душа перфекциониста требует избавления от уродливых костылей.
                +1
                Наследование моделей — это синтаксический сахар к OneToOneField (imho очень редко когда нужный); в базе при наследовании от User данные располагались в разных таблицах. С AUTH_USER_MODEL — в одной таблице (+ обязательных полей вроде меньше).
                +2
                Очень круто, можно будет наконец-то сделать нативную авторизацию через email в качестве username без применения доп. костылей
                  0
                  Лолчто, она и так была всегда безо всякий костылей, на это оабсолютно никак не влияло использование стандартной модели django. У меня во всех проектах авторизация по емейлу
                    0
                    Ограничение символов username — 30 вместо 75, если я не ошибаюсь, а чтобы обойти это ограничение нужны такие костыли…
                      0
                      А причем здесь username? Кастомная авторизация у меня работала именно по полю емейла. Вот username надо было чем-то забивать — это был неольшой костяль, да :)
                        0
                        *небольшой костыль
                  –1
                  В детстве был любимый мой фильм.
                  –2
                  О господи…
                    0
                    user = models.ForeignKey(settings.AUTH_USER_MODEL)

                    мне становится как-то не по себе, если этот паттерн войдет в моду. :/
                      +3
                      возможно, в моду войдет паттерн еще покруче:

                      user = models.ForeignKey(getattr(settings, "AUTH_USER_MODEL", "auth.User"))
                      
                        0
                        Вряд ли :-)

                        AUTH_USER_MODEL = 'auth.User'

                        скорее всего определят в django.conf.global_settings.
                          0
                          Я про приложения, которым нужно поддерживать django < 1.5.

                          В 1.4, впрочем, заглушку добавят, наверное — да и ничто не мешает просить пользователей в settings руками настройку добавить так-то.
                            0
                            волнует не сколько конкрентая ситуация, а вообще данный способ реализации dependency injection, внутри django. ведь разработчики примут это за best practices и начнут подражать направо и налево. в пределе — все ссылки внутри ForeignKey заменяются константами из settings — что дикий ужаснах.
                        +2
                        Судя по докам, там как-то так:

                        from django.contrib.auth import get_user_model
                        
                        class Post(models.Model):
                            user = models.ForeignKey(get_user_model())
                        

                        То есть вроде бы как интерфейс учтён.
                          0
                          А вот ещё только что подумалось:

                          1. В django.contrib.auth.models переименовываем модель User в UserModel
                          2. Там же, в django.contrib.auth.models, переопределяем User:

                            User = get_user_model()

                          3. В django.conf.global_settings указываем AUTH_USER_MODEL = 'auth.UserModel'


                          Походу, тогда и с обратной совместимостью проблем не возникнет.

                            0
                            Только циклические импорты будут
                              0
                              Хм. Я не заметил. Где именно они возникнут?
                                0
                                в get_user_model() придётся импортировать модуль из settings.AUTH_USER_MODEL, а в этом модуле нужно импортировать auth.models, чтобы унаследоваться от стандартного User
                                  0
                                  в get_user_model() придётся импортировать модуль из settings.AUTH_USER_MODEL,


                                  В текущей реализации get_user_model используется стандартная джангина get_model, например.
                                    0
                                    которая импортирует все модели, но потом не при импорте пакета, а

                                    User = get_user_model()
                                    

                                    выполнится при импорте django.auth.models
                                      0
                                      А, понятно. А если так?

                                      User = lazy_object(get_user_model())
                                      

                                        0
                                        Так работать будет, но всякие lazy штучки — абстракция дырявая, когда не реализовано на уровне языка.

                                        Что, например, вернёт type(User) в таком случае? Или что будет когда кто-то попытается отнаследоваться от такого User? В общем, такое решение приведёт к не очевидному поведению и фрустрации разработчиков. Удобство не окупится.
                                          0
                                          Чёрт, убедительно.

                                          Хотя type(User) в реальном коде маловероятно, а наследоваться уже и не понадобится в принципе, на такие усложнения не пойдут. Но сама идея-то хороша, согласитесь?

                                          Пожалуй, всё-таки надо подумать. Авось и найдётся обход этих импортов.
                          0
                          Вот он — прорыв года! Сегодня я усну спокойным за судьбу человечества… (кстати как раз недавно думал по этому поводу — «доколе?»)
                            –1
                            Oh no! Шесть лет! Шесть! Можете минусовать, но что-то мне подсказывает, что я не зря с Django на RoR перешел… ИМХО, такое медленное развитие не по мне.

                            Что ни говорите, но настолько долгий процесс внесения изменений ради обратной совместимости — это ужас. RoR живут на edge, но при этом умудряются плагины поддерживать на две ветки.

                            Надеюсь, Django выберется из болота и начнет обгонять конкурентов семимильными шагами. (=
                              +1
                              В RoR зато на обратную совместимость плюют с крыши офиса 37signals.
                                0
                                Скажем так, это утверждение очень голословно.

                                Во-первых, не надо всюду пихать 37signals. Они не одни Rails продвигают, и DHH сейчас не один core-разработчик, который сделал огромный вклад в Rails — есть еще к примеру Yehuda Katz, Aaron Paterson, Jose Valim, да и многие многие другие.

                                Во-вторых, как я уже сказал, на обратную совместимость в Rails не плюют, а даже наоборот, но не следуют такой фанатичности как Django. Если обратная совместимость заставляет отказываться от того, чтобы внедрять ежедневно нужные вещи в фреймворк, или не трогать откровенно ужасные и вырвиглазные решения, то такая совместимость не нужна по определению, так как каждый раз писать и прикручивать костыли в каждый проект — извините, у меня нет столько времени.

                                И может мне кто-нибудь объяснить, откуда пошел такой миф, о том, что в Ruby, и в Rails плюют на обратную совместимость приложений, и что на это смотрят с усмешкой? Раньше тоже верил, только глядя со стороны, но если Вы верите в такой миф — то окунитесь глубже и разберитесь в проблеме, почему фреймворк, который был менее популярен чем Django, сейчас является самым востребованным, и почему заказчики и разработчики по всему миру используют именно его, а не Django. Конечно, советую смотреть не относительно «трендовости» — отбросьте эту чепуху. Советую смотреть по реальным профитам использования инструмента, которые реально котируются в разработке ПО.
                                  0
                                  >Вы верите в такой миф — то окунитесь глубже и разберитесь в проблеме, почему фреймворк, который был менее популярен чем Django, сейчас является самым востребованным, и почему заказчики и разработчики по всему миру используют именно его, а не Django.

                                  Дефецит кадров на него чуть больше, что выражается в средних зарплатах на рынке труда, это да, но разработчики под битрикс еще дороже, так что не показатель.

                                  А вот по релизящимся и активно развивающимся проектам статистика, на мой взгляд, не столь однозначная.
                                +2
                                Так может показаться только человеку далёкому от Django. На самом деле, данный пример не показателен, Django отлично развивается, да и данное нововведение не настолько нужно, насколько просто приятно, поэтому, видимо, с ним и не торопились. Добавление доп. данных к юзеру и раньше вполне решалось, пусть и не столь элегантно.
                                  +1
                                  На данный момент — да, уже полгода как отдалился (=

                                  Django развивается, и я с этим совсем не спорю, но просто расширив свой кругозор, поработав на Rails, Flask, покопавшись в Pylons и Pyramid наконец, я понял, что Django — дает мне только 10 процентов того, что мне действительно нужно ежедневно. И модель ее развития меня совершенно не устраивает в плане использования ее как инструмента.

                                  У меня свои оскомины, и мое мнение остается моим мнением (= Холивары разводить не собираюсь и не хочу, лишь высказал свое IMHO.

                                  Просто в один момент, настал момент, когда я начал смотреть, и понял, что вот эти вещи делать можно, но не элегантно, и тут надо бы свое напильником допиливать, да и тут не совсем то, что хочу, а тут ад с формами, а тут это не устраивает, а это неудобно. Django — великолепный инструмент, но не настолько элегантный, чтобы я его любил и дальше.
                                +1
                                Ещё из заметных фишек в 1.5 обещают встроенную систему миграций. Пилит кажется один из авторов South.
                                Ну, и экспериментальная поддержка Py3k.
                                  0
                                  Меня бы полностью устроил просто включенный south. Впрочем, south включить столь несложно, так что ничего трогать не надо.
                                    –1
                                    Имхо, миграции south ужасны, у django-evolution более красивый подход. Лучше бы они как-то иначе их делали, чем просто включали south в релиз
                                      0
                                      А что с ними не так?
                                      Ну есть затыки с null/blank или там проблема отсутствия кастом библиотек кроме datetime при запуске. Но для питониста это самый простой класс проблем, можно написать препроцессор для миграций (так и ренеймы полей можно делать) или прогрузить библиотеки из __init__.py.
                                      Но благодаря ему я застрахован от более важного класса проблем, когда что-то не то происходит с базой (сбиваются привязки, дохнут индексы и т.д.)
                                        0
                                        Ну, когда пытаешься развернуть с нуля приложение, в котором когда-то использовались миграции, приходится, как минимум вырубать south нафиг, что уеже костыль.

                                        >Но для питониста это самый простой класс проблем, можно написать препроцессор для миграций (так и ренеймы полей можно делать) или прогрузить библиотеки из __init__.py.

                                        Такие решения должны работать из коробки
                                          +1
                                          Ну, когда пытаешься развернуть с нуля приложение, в котором когда-то использовались миграции, приходится, как минимум вырубать south нафиг, что уеже костыль.


                                          Чукча не читатель, чукча писатель :)

                                          Для таких случаев есть опция --fake
                                            0
                                            Хм, спасибо, но я так понимаю, что все равно придется запускать миграции для все приложений подряд >.> пусть и с этим флагом
                                              0
                                              Запускать с этим флагом нужно только те миграции, которые конфликтуют. Обычно так бывает при конкурентной разработки одного приложения несколькими программистами. Конфликты, как правило, разрешаются на раз-два.
                                            0
                                            >Ну, когда пытаешься развернуть с нуля приложение, в котором когда-то использовались миграции, приходится, как минимум вырубать south нафиг, что уеже костыль.

                                            А что именно при этом мешает?

                                            >Такие решения должны работать из коробки

                                            По моему скромному мнению, многие вещи лучше контролировать вручную, меньше проблем будет. Например если одно поле заменилось кастом-полем или есть разрыв в истории миграций. Мне при таких случаях вообще не интересно, что авторы коробки по этому поводу предполагали, если это отличается от «не трогать».
                                              0
                                              Вручную — можно и INSERT руками тогда делать :)
                                                0
                                                Юмор понял, но если авторы при необходимости INSERT пытаются творить какую-то «магию», то я лучше сделаю его сам :)
                                          0
                                          У эволюшена более красивый? Интересно, чем же. И вообще, он разве ещё развивается?
                                            0
                                            Нет, он, к сожалению, загнулся.
                                              0
                                              Ну почему же к сожалению :-)
                                        0
                                        вроде писали недавно, что в 1.5 вряд ли миграции будут
                                          0
                                          Я не в курсе, как там формируется релиз. Просто увидел pull request внушительных размеров, решил, что его скоро вольют в основную ветку.
                                      0
                                      Ага, еще через пару лет уберут захардкоженый html из форм.
                                      И осознают, что свою админку они лепили вообще без понимания того, как должен быть устроен front-end, свое мнение о которой (экрана на три) я осталю при себе, отослав к мнению sehmachine.

                                      После косой дюжины очень разных проектов на Django, я пришел к выводу, что теперь мы окончательно счастливы вместе с Tornado ws

                                      Only users with full accounts can post comments. Log in, please.