Es gibt verschiedene Möglichkeiten, mit dem Benutzermodell zu arbeiten, um ein Benutzerprofil zu erstellen und bestimmte Informationen hinzuzufügen, z. B. ein Profilfoto. Eine Möglichkeit besteht darin, ein Profilmodell mit einem OneToOneField für den Benutzer hinzuzufügen. Diese Option ist einfacher als das Proxying eines Modells oder das Überschreiben eines benutzerdefinierten Modells. Aber für mich persönlich hat sich die Neudefinition des Benutzermodells als effizienter erwiesen, was das Organisieren von Code und das Schreiben verschiedener Methoden betrifft, mit denen Sie die erforderlichen Informationen aus dem Benutzerobjekt in Vorlagen extrahieren können, ohne auf das Schreiben von Vorlagen-Tags zurückgreifen zu müssen.
Daher werden wir genau die Möglichkeit prüfen, das Benutzermodell in einem Django-Projekt zu überschreiben
Einführung
Als Einstieg möchte ich darauf hinweisen, dass es besser ist, das Benutzermodell ganz am Anfang des Projekts neu zu definieren, da es sonst zu Problemen bei Migrationen kommen kann, die manuell behoben werden müssen.
Ich selbst habe die Neudefinition des Benutzermodells bereits vorgenommen, als die Seite mehr als zwei Jahre bestand. Mein Überschreibungsprozess verlief jedoch relativ reibungslos, zumindest kann ich mich nicht erinnern, irgendwelche Probleme mit dem Überschreiben eines benutzerdefinierten Modells gehabt zu haben.
Neudefinition eines benutzerdefinierten Modells
Um das Benutzermodell korrekt zu überschreiben, müssen Sie das abstrakte Benutzermodell AbstractUser importieren und davon in der Anwendung erben, in der Sie das Modell haben werden.
In meiner App evileg_auth habe ich das so gemacht
# -*- coding: utf-8 -*- from django.contrib.auth.models import AbstractUser class User(AbstractUser): pass
Als nächstes müssen Sie dieses Modell als neues benutzerdefiniertes Modell in der Einstellungsdatei settings.py angeben.
AUTH_USER_MODEL = 'evileg_auth.User'
Dies ist erforderlich, damit eine Drittanbieteranwendung Ihr benutzerdefiniertes Modell anstelle des Standardmodells verwenden kann.
Anschließend können Sie Migrationen erstellen und das Projekt migrieren
python manage.py makemigrations python manage.py migrate
Vergessen Sie auch nicht, Ihr Modell im Admin-Bereich zu registrieren
# -*- coding: utf-8 -*- from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import User admin.site.register(User, UserAdmin)
Anmerkungen
Wenn Sie ein überschriebenes benutzerdefiniertes Modell in ein vorhandenes Projekt implementieren, empfehle ich Ihnen, die folgenden Schritte auszuführen, um sicherzustellen, dass das überschriebene Modell in Ihrem gesamten Projekt verwendet wird.
Einstellungen.AUTH_USER_MODEL
Verwenden Sie in allen models.py -Dateien die Variable settings.AUTH_USER_MODEL aus den Einstellungen anstelle des Standardmodells.
# -*- 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()
Überall in Ihrem Code, der davon ausgeht, dass bereits eine Django-Instanz ausgeführt wird, verwenden Sie das dynamische Abrufen der Benutzermodellklasse über get_user_model()
Ich habe zum Beispiel dieses 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)
Anwendung von Drittanbietern
Wenn Sie eine Drittanbieteranwendung schreiben, sollten die Empfehlungen im Abschnitt „Hinweise“ für Sie obligatorisch sein, da Ihre Drittanbieteranwendung sonst für die Entwickler nutzlos ist, die benutzerdefinierte Modelle in ihren Django -Projekten überschreiben
Vorteile des Überschreibens eines benutzerdefinierten Modells
Das Überschreiben des Benutzermodells hat meiner Meinung nach große Vorteile gegenüber der Verwendung von OneToOneField, da Sie damit den Objektmanager ohne Krücken überschreiben und auch eine Reihe von Methoden hinzufügen können, die in Ihrem Projekt nützlich sein können. Und auch diese Methoden können in Templates aufgerufen werden, ohne Template-Tags zu schreiben.
Hier ist ein Beispiel für ein benutzerdefiniertes Modellteil in meinem Projekt
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})
Zumindest habe ich es immer versäumt, die Standardmethode get_absolute_url für ein Benutzerprofil auf einer Website zu verwenden.
Полезный урок, весьма лучше, чем создать профиль. А как всё это объединить в админке? admin.site.register(User, UserAdmin) - UserAdmin убрал мое созданное поле для абстрактного поля.
Я немного не понял, что именно вы хотите объединить? Вы хотите, чтобы группы и пользователи были в одном groupbox'e?
Или хотите видеть абстрактное поле? Если абстрактное поле, то наследуйтесь от UserAdmin и переопределите переменные fields и т.д., как если бы наследовались от ModelAdmin
Я уже нашел в вашем другом уроке как добавить поле аватар к пользователям. Именно то что вы написали) Спасяб:3
Да ещё бы хотелось чтоб группы и пользователи были в одной группе.
Насчёт такого никогда не заморачивался, мне это не мешало. Но вообще для этого можно использовать прокси модель.
Думаю, что это может выглядеть так
Суть в том, что проксируем стандартную модель Groups в другое приложение, чтобы они отображались в одном app
Благодарю!
Подскажите, эта серия уроков для django 2.0?
Я ещё не переходил на Django 3, поэтому на данный момент все примеры пишутся с использованием Django 2, наиболее старые с использованием Django 1.
Но в принципе, большая часть из статей должна работать и с Django 3. Хотя и не все.
Понял, большое спасибо! Буду ждать перехода на 3 версию :)
Я тоже его жду. Вернее жду, когда все разработчики третьесторонних библиотек добавят поддержку третьей версии.
Добрый день, Я вот написал в admin.py
admin.site.register(User, UserAdmin)
Но у меня не появилось новые поля в админке?
Если у вашего пользователя нет прав но чтение или изменение модели пользователя, то вы можете и не увидеть эту модель в админке. В этом случае лучше под суперпользователем проверять всё.
А как дать ему эти права?
В данном случае я заходил под superuser но все равно не появлялись эти поля
def initials(self):
return get_initials(self)
В последнем листинге что такое get_initials(self), пайчарм подчеркивает и предлагает создать функцию get_initials
Лишний кусок кода (Метод для получения инициалов), удалите его.