Evgenij LegotskojApril 26, 2020, 3:08 p.m.

Django - Tutorial 052. Redefining a User Model

Content

There are various options for working with a user model for creating a user profile and adding some specific information, for example, a profile photo. One way is to add a profile model with the OneToOneField field for the user. This option is simpler than a proxy model or overriding a user model. But for me personally, redefinition of the user model turned out to be more effective in terms of organizing code and writing various methods that allow you to extract the necessary information from the user object in templates without resorting to writing template tags.

Therefore, let's consider exactly the option of redefining the user model in a project in Django

Introduction

As an introduction, I’ll draw your attention to the fact that redefining a user model is best done at the very beginning of the project, otherwise there may be problems with migrations that need to be fixed manually.

I myself did overriding the user model already when the site existed for more than two years. However, my redefinition process went relatively smoothly, at least I don’t remember that there were any problems with the fact that I redefined the user model.

User Model Override

In order to correctly redefine the user model, you need to import the abstract user model AbstractUser and inherit from it in the application where you will have the model.

In my application evileg_auth I did it this way

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

from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    pass

Next, you need to specify this model as the new user model in the settings file settings.py

AUTH_USER_MODEL = 'evileg_auth.User'

This is necessary so that a third-party application starts using your user model instead of the standard one.

Then you can create migrations and migrate the project

python manage.py makemigrations
python manage.py migrate

Also do not forget to register your model in the admin panel

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

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

from .models import User

admin.site.register(User, UserAdmin)

Notes

If you are introducing an overridden user model into an existing project, I recommend that you follow these steps so that the overridden model is used everywhere in your project.

settings.AUTH_USER_MODEL

In all models.py files, use the settings.AUTH_USER_MODEL variable from the settings instead of the standard 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()

Everywhere in the code where it is assumed that the Django instance is already running, use the dynamic get of the user model class via get_user_model()

For example, I have such a 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)

Third Party Application

If you are writing a third-party application, then the recommendations from the notes section should be mandatory for you, because otherwise your third-party application will be useless for those developers who redefine custom models in their projects on Django

Benefits of Overriding a Custom Model

Redefining the user model has, in my opinion, great advantages compared to using OneToOneField, since it allows you to redefine the object manager without crutches, as well as add a number of methods that can be useful in your project. And also these methods can be called in templates without writing template tags.

Here is an example of a part of a user model in my project

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)

At a minimum, I always lacked the use of the standard method get_absolute_url for the user profile on the site.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
- company blog
Support the author 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

Благодарю!

  • #
  • May 4, 2020, 5:56 a.m.

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

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

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

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

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

t
  • #
  • Jan. 23, 2021, 8:28 a.m.

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

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

t

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

t
  • #
  • Feb. 24, 2021, 2:56 a.m.

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

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Timeweb

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting
SG

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

  • Result:0points,
  • Rating points-10
a

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
M
  • Mili
  • Feb. 18, 2021, 9:22 a.m.

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

  • Result:50points,
  • Rating points-4
Last comments
t
  • t1m4
  • Feb. 24, 2021, 2:56 a.m.

Django - Tutorial 052. Redefining a User Model

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

Django - Tutorial 001. Deploying a site on Django + PostgreSQL + Gunicorn + Nginx

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

Django - Tutorial 052. Redefining a User Model

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

Django - Tutorial 001. Deploying a site on Django + PostgreSQL + Gunicorn + Nginx

Всё по мануалу выше, буква в букву. gunicorn mysite.wsgi:application server { listen 80; server_name 10.0.3.15; access_log /var/log/nginx/example.log; locat…
Now discuss on the forum
M

нужна помощь с проектом qt c++

дали задание, на несколько дней. собираюсь делать, но хотел бы получить помощь более опытных людей, чтобы подкорректировать себя и подстраховаться. каким образом это можно сделать? …

QScrollArea dynamically add QCheckBoxes

Всё правильно. Это просто спамер, который отправился в вечный бан.
Ds

При рендере тайлов появляется buffer reallocation

upd. с помощью double commander в сырцах OpenStreetMap плагина нашёл такую функцию size_t CoordBuffer::PushCoord(double x, double y) { if (usedPoints>=bufferSize) { buff…
GF

Сигналы и слоты в PyQt5

Решение стало следующим: после конвертации файла Ui из QtDesigner мне никак не выгодно продолжать работать в этом же файле, т.к. я постоянно продолжаю дорабатывать интерфейс, а его поведение я о…

Получение даты сборки программы

Проблему решил так: В .pro файле: VERSION = 1.2.3DEFINES += APP_VERSION=\\\"$$VERSION\\\"#Формирование даты и времени сборки (меняется при полной пересборке проекта)win32:{BLD_DATE=…
About
Services
© EVILEG 2015-2020
Recommend hosting TIMEWEB