Евгений Легоцкой26 апреля 2020 г. 15:08

Django - Урок 052. Переопределение модели пользователя

Содержание

Есть разные варианты работы с пользовательской моделью для создания профиля пользователя и добавления некоторой специфичной инфоромации, например, фото в профиле. Одним из способов является добавление модели профиля с OneToOneField полем для пользователя. Данный вариант является более просты, чем прокси модели или переопределение модели пользователя. Но лично для меня переопределение модели пользователя оказалось более эффективным в плане организации кода и написании различных методов, которые позволяет извлекать нужную информацию из объекта пользователя в шаблонах не прибегая к написанию шаблонных тегов.

Поэтому давайте рассматрим именно вариант переопределения модели пользователя в проекте на Django

Введение

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

Сам же я делал переопределение пользовательской модели уже, когда сайт существовал уже более двух лет. Однако у меня процес переопределения прошёл относительно без проблем, по крайней мере я не помню, чтобы были какие-то проблемы с тем, что я переопределил модель пользователя.

Переопределение модели пользователя

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

В своём приложении evileg_auth я сделал это таким образом

# -*- coding: utf-8 -*-

from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    pass

Далее вам необходимо указать эту модель в качестве новой модели пользователя в файле настроек settings.py

AUTH_USER_MODEL = 'evileg_auth.User'

Это необходимо для того, чтобы третье сторонние приложение начали использовать вашу модель пользователя вместо стандартной.

После чего можете создать миграции и мигрировать проект

python manage.py makemigrations
python manage.py migrate

Также не забудьте зарегистрировать свою модель в административной панели

# -*- coding: utf-8 -*-

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .models import User

admin.site.register(User, UserAdmin)

Примечания

Если вы внедряете переопределённую модель пользователя в уже существующий проект, то рекомендую выполнить следующие действия, чтобы переопределённая модель использовалась везде в вашем проекте.

settings.AUTH_USER_MODEL

Во всех файлах models.py используйте вместо стандартной модели переменную settings.AUTH_USER_MODEL из настроек

# -*- coding: utf-8 -*-

from django.conf import settings
from django.db import models


class SomeModel(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='User')

get_user_model()

Везде в коде, где предполагается, что инстанс Django уже запущен, используйте динамическое получение класса модели пользователя через get_user_model()

Например, у меня есть такой mixin

class EInUserProfileMixin:
    user_profile = None

    def dispatch(self, request, *args, **kwargs):
        self.user_profile = get_object_or_404(get_user_model(), username=kwargs['user'], is_active=True)
        return super().dispatch(request, *args, **kwargs)

Третьестороннее приложение

Если вы пишите третьестороннее приложение, то рекомендации из раздела примечания для вас должны быть обязательными, поскольку в противном случае ваше третьестороннее приложения будет бесполезным для тех разработчиков, которые переопределяют пользовательские модели в своих проектах на Django

Преимущества переопределения пользовательской модели

Переопределение пользовательской модели имеет, на мой взгляд, большие преимущества по сравнению с использованием OneToOneField, поскольку позволяет без костылей переопределить менеджер объектов, а также добавить ряд методов, которые могут быть полезны в вашем проекте. А также эти методы можно будет вызывать в шаблонах без написания шаблонных тегов.

Вот например часть пользовательской модели в моём проекте

class User(AbstractUser):

    last_online = models.DateTimeField(blank=True, null=True)

    objects = UserManager()

    class Meta:
        ordering = ['username']

    def get_absolute_url(self):
        return reverse('users:profile', kwargs={'user': self.username})

    def initials(self):
        return get_initials(self)

Как минимум мне всегда не хватало использования стандартного метода get_absolute_url для профиля пользователя на сайте.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
- блог компании
Поддержать автора Donate

Полезный урок, весьма лучше, чем создать профиль. А как всё это объединить в админке? admin.site.register(User, UserAdmin) - UserAdmin убрал мое созданное поле для абстрактного поля.

Я немного не понял, что именно вы хотите объединить? Вы хотите, чтобы группы и пользователи были в одном groupbox'e?
Или хотите видеть абстрактное поле? Если абстрактное поле, то наследуйтесь от UserAdmin и переопределите переменные fields и т.д., как если бы наследовались от ModelAdmin

Я уже нашел в вашем другом уроке как добавить поле аватар к пользователям. Именно то что вы написали) Спасяб:3
Да ещё бы хотелось чтоб группы и пользователи были в одной группе.

Да ещё бы хотелось чтоб группы и пользователи были в одной группе.

Насчёт такого никогда не заморачивался, мне это не мешало. Но вообще для этого можно использовать прокси модель.

Думаю, что это может выглядеть так

class ProxyGroups(Groups):
    class Meta:
        proxy = True    
        # Если определить ProxyGroup внутри my_auth/models.py,
        # то его app_label будет установлен как 'my_auth' автоматически.
        # Или можно переопределить его так           
        # app_label = 'my_auth'

        # также можно установить некоторые параметры из существующего Group
        # verbose_name = Groups._meta.verbose_name
        # verbose_name_plural = Groups._meta.verbose_name_plural


# in admin.py
admin.site.register(ProxyGroups)

Суть в том, что проксируем стандартную модель Groups в другое приложение, чтобы они отображались в одном app

Благодарю!

  • #
  • 4 мая 2020 г. 5:56

Подскажите, эта серия уроков для django 2.0?

Я ещё не переходил на Django 3, поэтому на данный момент все примеры пишутся с использованием Django 2, наиболее старые с использованием Django 1.

Но в принципе, большая часть из статей должна работать и с Django 3. Хотя и не все.

Понял, большое спасибо! Буду ждать перехода на 3 версию :)

Я тоже его жду. Вернее жду, когда все разработчики третьесторонних библиотек добавят поддержку третьей версии.

t
  • #
  • 23 января 2021 г. 8:28

Добрый день, Я вот написал в admin.py
admin.site.register(User, UserAdmin)
Но у меня не появилось новые поля в админке?

Если у вашего пользователя нет прав но чтение или изменение модели пользователя, то вы можете и не увидеть эту модель в админке. В этом случае лучше под суперпользователем проверять всё.

t

А как дать ему эти права?

t
  • #
  • 24 февраля 2021 г. 2:56

В данном случае я заходил под superuser но все равно не появлялись эти поля

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Timeweb

Позвольте мне порекомендовать вам отличный хостинг, на котором расположен EVILEG.

В течение многих лет Timeweb доказывает свою стабильность.

Для проектов на Django рекомендую VDS хостинг

Посмотреть Хостинг
НИ

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:90баллов,
  • Очки рейтинга8
НИ

C++ - Тест 003. Условия и циклы

  • Результат:92баллов,
  • Очки рейтинга8
НИ

C++ - Тест 001. Первая программа и типы данных

  • Результат:80баллов,
  • Очки рейтинга4
Последние комментарии
D

Django - Урок 001. Развёртывание сайта на Django + PostgreSQL + Gunicorn + Nginx

А почему нельзя? Где можно об этом почитать? Киньте, пожалуйста, в меня ссылкой.
D

Django - Урок 049. Оптимизация производительности Django на примере боевого проекта

Огромное спасибо вам за статью! Для меня стали открытием select_related и prefetch_related
t
  • t1m4
  • 24 февраля 2021 г. 2:56

Django - Урок 052. Переопределение модели пользователя

В данном случае я заходил под superuser но все равно не появлялись эти поля

Django - Урок 001. Развёртывание сайта на Django + PostgreSQL + Gunicorn + Nginx

Поднял сервис с помощью systemd, вот по этому мануалу: https://habr.com/ru/post/501414/
t
  • t1m4
  • 23 февраля 2021 г. 7:11

Django - Урок 052. Переопределение модели пользователя

А как дать ему эти права?
Сейчас обсуждают на форуме
S

Помощь в проекте qt, qml

Доброго времени суток! Хотелось бы получить консультативную помощь по проекту, т.к. имеются определенные затыки, которые своими силами преодолеть не получается. За труды по наущению меня ум…

Добавление данных в модель из textEdit

ознакомьтесь с этим и этим для понимания принципов работы с моделями, и поймете что у вас не так
  • BlinCT
  • 6 марта 2021 г. 10:57

Работа с QJsonObject и получение данных из него

Вопрос решен. Оказалось что я не очень внимательно прочитал описание метода root.take("devices") Оказывается он удаляте ключ, а занчит и все данные по нему. И по этому после этого…

Как совместить таблицу и дерево в Qt

Добрый день. Имеется таблица QTableView, нужно у некоторых строк сделать возможность раскрытий, как в QTreeVidget и отоборажать в них аналогичные строки. Скажите пожалуйста, как это мо…
KM

не получаеться добавить списки в списокб ошибка в петле

решение: с line 99: listy = [] lista = [] for single_lp in max_list_from_all_plates: suma = 0 lists = [] for sign in single_lp: Highest_score=0 bigl…
О нас
Услуги
© EVILEG 2015-2020
Рекомендует хостинг TIMEWEB