Abstractuser — Django модель AbstractUser


Содержание

Почему требуется изменить AUTH_USER_MODEL для подкласса AbstractUser?

0 vmonteco [2020-07-19 18:47:00]

После создания проекта, а затем приложения и добавления этого приложения в мой INSTALLED_APPS , я попытался создать пользовательский класс пользователя, models.py подкласс AbstractUser в моих models.py :

Затем я попытался запустить makemigrations и я получил эту ошибку:

Добавление AUTH_USER_MODEL = ‘main.CustomUser’ ( main это мое приложение), кажется, решить эту проблему ( makemigrations преуспевает, как migrate ), но я не понимаю, почему я получаю эту ошибку, даже если я просто определить этот подкласс фактически не использовать его все же.

Я хотел бы понять, почему эта проблема возникла на первом месте, и как это AUTH_USER_MODEL решение AUTH_USER_MODEL . Я действительно не понимаю, почему это похоже на конфликт между моим CustomUser и auth.User .

django django-migrations django-custom-user

2 ответа

1 Решение kapilsdv [2020-07-19 19:34:00]

Ваша пользовательская модель пользователя наследует AbstractUser который является модельным классом django.contrib.auth .

AbstractUser определяет себя из моделей AbstractBaseUser и PermissionsMixin и, таким образом, связан с моделью Group и Permission через класс PermissionsMixin

PermissionsMixin определяет ManyToManyField отношения к Permission и Groups (которые далее связанное ManyToMany с Permission ) моделью, как:

PermissionsMixin определяет related_name=»user_set» с моделями Permission и Group и, таким образом, модель AbstractUser имеет обратное отношение к этим моделям.

Когда вы подклассифицируете AbstractUser , вы определяете две модели, которые имеют обратную связь с Group и Permission с тем же related_name .

Но у вас не может быть двух общих или внешних ключей с одинаковыми ссылочными именами, указывающими на одну и ту же модель.

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

Поэтому в вашем приложении может быть только один подкласс AbstractUser .

Если вы подклассифицируете AbstractUser тогда вы должны указать эту дочернюю модель на AUTH_USER_MODEL, чтобы ваше приложение указывало на один экземпляр AbstractUser, а не на два.

Поскольку AbstractUser (или, скорее, PermissionMixin, который он наследует) определяет отношения с этими другими моделями — то есть группами, разрешениями — и он использует жестко закодированный атрибут related_name, user_set , чтобы избежать путаницы, если модель была заменена.

Это прекрасно, пока класс остается абстрактным, но как только вы определите конкретный подкласс, Django определит обратные отношения к этой модели; теперь у вас есть две модели, которые используют одно и то же значение user_set , в качестве связанного имени из группы.

Если вы установили AUTH_USER_MODEL, то Django больше не определяет стандартный класс User; так что вы вернетесь к ситуации, когда только один класс использует это имя_соединения.

AbstractUser Джанго полный пример

Я новичок в Django, и я пытался это в течение нескольких недель, но не мог найти способ, чтобы решить эту проблему.

Я хочу, чтобы хранить дополнительную информацию, как пользовательский мобильный номер, название банка, банковский счет. И хотите сохранить номер мобильного телефона в то время как пользователь регистрируется и хочет пользователю войти в систему с любым (номер мобильного телефона и пароль) или (адрес электронной почты и пароль).

Это моя UserProfile модель

И это мой forms.py

В моем settings.py я включил

admin.py моего приложения является

При добавлении пользователя от администратора Я получаю эту ошибку

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

При регистрации в регистрационной форме я также получаю эту ошибку


2 ответа

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

Вопрос по django &#8211 Разница между AbstractUser и AbstractBaseUser в Джанго?

Использование AbstractUser а также AbstractBaseUser выглядит довольно похоже.

Какая разница между двумя?

AbstractUser в основном простоПользователь» класс тывероятно, уже привык. AbstractBaseUser делает меньше предположений, и вы должны указать ему, какое поле представляет имя пользователя, какие поля являются обязательными и как управлять этими пользователями.

Если ты’просто добавьте вещи к существующему пользователю (то есть данные профиля с дополнительными полями), а затем используйте AbstractUser, потому что он ‘проще и проще. Если вы хотите переосмыслить некоторые из ДжангоЕсли исходить из предположений об аутентификации, то AbstractBaseUser дает вам возможность сделать это.

документация объясняет это полностью. AbstractUser является полной моделью пользователя, дополненной полями, как абстрактный класс, так что вы можете наследовать его и добавлять собственные поля профиля и методы. AbstractBaseUser содержит только функции аутентификации, но не содержит реальных полей: вы должны указывать их при создании подкласса.

Creating a Custom User Model in Django

Creating a Custom User Model in Django

Posted by Michael Herman | Last updated on February 7th, 2020

Posted by Michael Herman
Last updated on February 7th, 2020

How do I fully replace the username field with an email field for Django authentication?

This post explains step-by-step how to create a custom User model in Django so that an email address can be used as the primary user identifier instead of a username for authentication.

Keep in mind that the process outlined in this post requires significant changes to the database schema. Because of this, it’s only recommended for new projects. If this is for an existing legacy project, you’ll probably have to back up the data and recreate the database. For more on this, review the following resources:

AbstractUser vs AbstractBaseUser

The default User model in Django uses a username to uniquely identify a user during authentication. If you’d rather use an email address, you will need to create a custom User model by either subclassing AbstractUser or AbstractBaseUser .

  1. AbstractUser : Use this option if you are happy with the existing fields on the User model and just want to remove the username field.
  2. AbstractBaseUser : Use this option if you want to start from scratch by creating your own, completely new User model.

The steps are the same for each:

  1. Create a custom User model and Manager
  2. Update settings.py
  3. Customize the UserCreationForm and UserChangeForm forms
  4. Update the admin

It’s highly recommended to set up a custom User model when starting a new Django project. Without it, you will need to create another model (like UserProfile ) and link it to the Django User model with a OneToOneField if you want to add new fields to the User model.

Project Setup

Assuming you have Pipenv installed, start by creating a new Django project along with a users app:

DO NOT apply the migrations. Remember: You must create the custom User model before you apply your first migration.

Add the new app to the INSTALLED_APPS list in settings.py:

Tests

Let’s take a test-first approach:

Add the specs to users/tests.py, and then make sure the tests fail.

Model Manager


First, we need to add a custom Manager, by subclassing BaseUserManager , that uses an email as the unique identifier instead of a username.

Create a managers.py file in the «users» directory:

User Model

Decide which option you’d like to use—subclassing AbstractUser or AbstractBaseUser .

AbstractUser

  1. Created a new class called CustomUser that subclasses AbstractUser
  2. Removed the username field
  3. Made the email field required and unique
  4. Set the USERNAME_FIELD —which defines the unique identifier for the User model—to email
  5. Specified that all objects for the class come from the CustomUserManager

AbstractBaseUser

  1. Created a new class called CustomUser that subclasses AbstractBaseUser
  2. Added fields for email , is_staff , is_active , and date_joined
  3. Set the USERNAME_FIELD —which defines the unique identifier for the User model—to email
  4. Specified that all objects for the class come from the CustomUserManager

Settings

Add the following line to the settings.py file so that Django knows to use the new User class:

Now, you can create and apply the migrations, which will create a new database that uses the custom User model. Before we do that, let’s look at what the migration will actually look like without creating the migration file, with the —dry-run flag:

You should see something similar to:

If you went the AbstractBaseUser route, you won’t have fields for first_name or last_name . Why?

Make sure the migration does not include a username field. Then, create and apply the migration:

View the schema:

If you went the AbstractBaseUser route, why is last_login part of the model?

You can now reference the User model with either get_user_model() or settings.AUTH_USER_MODEL . Refer to Referencing the User model from the official docs for more info.

Also, when you create a superuser, you should be prompted to enter an email rather than a username:

Цукерберг рекомендует:  JavaScript селекторы

Make sure the tests pass:

Forms

Next, let’s subclass the UserCreationForm and UserChangeForm forms so that they use the new CustomUser model.

Create a new file in «users» called forms.py:

Admin

Tell the admin to use these forms by subclassing UserAdmin in users/admin.py:

That’s it. Run the server and log in to the admin site. You should be able to add and change users like normal.

Conclusion

In this post, we looked at how to create a custom User model so that an email address can be used as the primary user identifier instead of a username for authentication.

You can find the final code for both options, AbstractUser and AbstractBaseUser , in the django-custom-user-model repo. The final code examples include the templates, views, and URLs required for user authentication as well.


Want to learn more about customizing the Django user model? Check out the following resources:

Join our mailing list to be notified about course updates and new tutorials.
Authentication with Flask, React, and Docker

Get the full course. Learn how to add authentication to a Flask and React microservice.

Authentication with Flask, React, and Docker

Get the full course. Learn how to add authentication to a Flask and React microservice.

apirobot

Blog about web development by Denis Orehovsky

Расширяем модель User в Django

Для работы с пользователями, Django предоставляет готовую модель User. Часто, одной этой модели недостаточно. Приходится ее расширять, либо переписывать, если не устраивает стандартная реализация.

Несколько причин, почему может не устраивать стандартная реализация:

  1. Вам нужно вместо двух полей first_name и last_name, одно поле full_name.
  2. Не устраивает то, что поле email – необязательно (blank=True).
  3. Не устраивает то, что USERNAME_FIELD = ‘username’. USERNAME_FIELD указывает на поле, которое является уникальным идентификатором для пользователя. Кроме того, это поле используется на странице с авторизацией. Получается, что по умолчанию, пользователь вводит username и password. Если вам нужна авторизация через email, то USERNAME_FIELD нужно переопределить на ‘email’.

Рекомендую посмотреть исходный код модели User здесь. Так будет проще понять, о чем я говорю.

В этом уроке поговорим о двух методах расширения модели User:

(1) Создание модели User, которая наследуется либо от AbstractUser, либо от AbstractBaseUser.

Класс AbstractUser, по функционалу, является той самой моделью User, которую вы получаете от Django из коробки. Если вас устраивает стандартная реализация, но нужно ее расширить, то наследуйтесь от AbstractUser. Если нет, то наследуйтесь от AbstractBaseUser и переопределяйте поля сами.

(2) Создание двух моделей: User и Profile, которые связаны друг с другом отношением один-к-одному (OneToOneField).

Зачем создавать две модели? Дело в том, что в программировании есть концепция Single Responsibility Principle (Принцип единственной обязанности).

«На каждый объект должна быть возложена одна единственная обязанность»

Single Responsibility Principle

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

Итак, следуя принципу единственной обязанности, мы создаем:

  1. Модель User, которая отвечает только за аутентификацию и авторизацию пользователя в системе.
  2. Модель Profile, которая хранит всевозможную информацию о пользователе для отображения на странице.

User, наследуемый от AbstractUser

Это самый простой способ, т.к. класс AbstractUser уже предоставляет все, что нужно.

Добавляем путь к модели User в настройках проекта, чтобы Django использовал нашу модель вместо стандартной:

User, наследуемый от AbstractBaseUser

  • USERNAME_FIELD – уникальный идентификатор пользователя. Это поле, вместе с паролем, используется при авторизации.
  • REQUIRED_FIELDS – список полей, которые потребуется ввести при создании пользователя через команду createsuperuser. Также этот список нередко используется сторонними библиотеками, при создании формы с регистрацией. Нормальная форма с регистрацией включает в себя: USERNAME_FIELD, REQUIRED_FIELDS и password.
  • is_active – активен ли пользователь или нет. Когда пользователь пытается удалить аккаунт, мы присваиваем полю is_active=false. Аккаунт из базы данных не удаляется. Это делается ради сохранения информации об активности пользователя.
  • is_staff – имеет ли пользователь доступ к панели администратора или нет.


Создаем свой UserManger и переопределяем методы, которые отвечают за создание пользователя:

Добавляем путь к модели User в настройках проекта, чтобы Django использовал нашу модель вместо стандартной:

User и Profile со связью один-к-одному

Модель User переопределять не будем. Возьмем ту, что предоставляет Django из коробки. Создадим модель Profile:

Осталось решить две проблемы:

  1. После создания пользователя, не создается новый Profile, прикрепленный к этому пользователю.
  2. После вызова метода save у пользователя, не вызывается метод save у прикрепленного к нему профиля. Из-за этого приходится каждый раз вызывать метод save после изменения профиля:

Signals to the rescue! Сигналы позволяют определённым отправителям (senders) уведомлять некоторый набор получателей (receivers) о совершении действий. Используем встроенный в Django сигнал post_save, который отсылается после завершения работы метода save:

Не забудьте подключить сигналы в методе ready конфигурационного класса:

Тестируем профиль через shell:

Напоследок хотелось бы сказать, что не стоит забывать про оптимизацию запросов к базе данных. По умолчанию, Django ORM не включает в результат связанные объекты. Поэтому, при каждом обращении к пользователю через профиль, делается новый запрос к базе данных:

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

Такая проблема решается с помощью метода select_related, который добавляет к результату запроса связанный объект:

Исправляем представление из предыдущего примера:

Заключение

В этом уроке мы поговорили о методах расширения модели User. Если вы не определились с выбором между User + Profile или просто User, то следуйте своему сердцу. После просмотра исходного кода проектов на GitHub, я понял, что каждый делает так, как хочет. В одних проектах всё пихают в модель User, в других используют User + Profile.

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

Разница между AbstractUser и AbstractBaseUser в Джанго?

использование AbstractUser и AbstractBaseUser очень похож.

в чем разница между этими двумя?

2 ответов

на документация объясняет это полностью. AbstractUser-это полная модель пользователя с полями как абстрактный класс, который можно наследовать и добавлять собственные поля и методы профиля. AbstractBaseUser содержит только функции аутентификации, но не фактические поля: вы должны предоставить их при подклассе.

в AbstractUser, по существу, просто «пользователь» класса, вы, вероятно, уже привыкли. AbstractBaseUser делает меньше предположений, и вы должны сказать ему, какое поле представляет имя пользователя, Какие поля требуются и как управлять этими пользователями.

Если вы просто добавляете вещи к существующему пользователю (т. е. данные профиля с дополнительными полями), используйте AbstractUser, потому что это проще и проще. Если вы хотите переосмыслить некоторые предположения Django об аутентификации, то AbstractBaseUser дает вам возможность сделать это.

Options & Objects: Customizing the Django User Model

Not long ago, I began working on a web application using the Django web framework where I wanted to sign users in using their phone number instead of the default username. In the process of figuring out the best way to do that, I found a lot of confusing or outdated documentation, which prompted me to propose a poster session on this topic for PyCon 2020 (and it got in!).

Unfortunately, aside from the awesomeness of my robot collage depicted in the tweet on the left, my poster didn’t make the trip home with me to San Francisco. I was also asked by some of the people who stopped by if I had examples of all three to point to someplace, which I didn’t at the time. Live and learn.

I got some nice compliments on the poster, in person and shown in the tweets on the left, but I thought full examples were a great piece of feedback, and would lead to a broader discussion of the nuances and tradeoffs of each option. In this post, I’ll outline what I learned putting together the poster, show some sample code for each possibility, and offer up some recommendations for the s ign-in-with-something-other-than-username use case based on my research and on the conversations I had at PyCon.

In this Github repo, you’ll find a basic, functional project with a simple implementation of each of the three options outlined on the poster. Links to the relevant files for each option inside the repo are included below for easy reference. In each, I’ve included a separate project and application for each option, all with a working template for front end authentication as well as a working superuser creation method that can be run in the command line.

All of the examples use Django 1.11 and Python 3.5.2. Each one adds a zip_code field to the User model as a CharField to keep it simple, and in the first two options, I make the email field the username .


Here I would like to pause and say that if you haven’t used Django, I recommend going through one or both of the excellent tutorials from DjangoGirls or the Django docs to get familiar with the framework before trying to follow this post. If you have worked with Django, you’re probably familiar with the User model, an out-of-the-box feature that you can make use of to authenticate users (a.k.a. create accounts and sign them in and out of your application) via a Python class that represents a table in the database and comes with a bunch of built in fields and methods for data retrieval and permissions that you can read about in the official docs.

Цукерберг рекомендует:  Итераторы в Ruby

Why this matters beyond the use case

Getting users to sign up for your product often isn’t easy or free, and when you finally get them through the funnel to the form, you want to balance making life as easy for them as possible with the information you need to collect. At the same time, you don’t want to have unnecessary fields sitting empty in your database.

If you’re using Django’s authentication features, you have three options for customizing your model, shown clockwise on the poster, starting on the top left:

Option 1: Create your own user model by subclassing Django’s AbstractBaseUser. This is great if you need a lot of flexibility in the content of the model, and how it is accessed and you don’t mind a little extra work at the start of your project.

Option 2: Extend the existing User Model with your own fields by subclassing Django’s AbstractUser. This option is ideal if you want to keep the default fields in the user model and you don’t need anything too different with permissions, but you want to change the username to a different field and/or add authentication fields.

Option 3: Add fields to the existing User > This method doesn’t really help if you want to change the username field, but it does enable you to link the User model to another model to store more data. It daisy chains two models together in the database, which would be useful if you want to store user data that doesn’t have anything to do with authentication or if some of the user’s data is needed by a third party service that you want to cordon off e. This was also the recommended way to customize a User model before version 1.5 Django, so quite a few existing applications use this method.

Of these three, the first two are really solid options for most use cases. At PyCon, I spoke to a few people who were interested in using options 1 or 2 but had Option 3 in place. In those cases, because you’re making fundamental changes to the database schema, the only course of action is to back up your data and recreate your models and database. This post is a couple of years old, but contains some solid advice.

This post won’t cover implementation of third party authentication services with Django, steps for migrating existing models or sending emails to users. That said, sending emails to authenticate new users with Django will be the subject of a future post!

Let’s get started.

Three Options, Step by Step

This is the highest difficulty, highest flexibility option.

Use this approach if you:

  • Want a lot of latitude to customize everything about your model
  • Want to minimize the number of fields for data collection and you don’t think you’ll use the ones that come out of the box
  • Have some time to put into writing some of the basic permissions you need to work with Django’s permissions model

The first part, covered in the poster, is writing your custom user model itself.

In your application folder, go to the models.py folder and add code along the lines of the following (with whatever fields you want, of course!):

There is a lot going on in this one, so let’s break it down a bit.

  • We need to add the unique=True parameter to whatever field we are using as the USERNAME_FIELD on line 6.
  • REQUIRED_FIELDS is a list of fields that will be mandatory to create a user. Note that including the USERNAME_FIELD here will give you an error when you try to run your app. Because I’ll create my form by importing and sublassing the UserCreationForm in my forms.py file, password doesn’t need to be added to the REQUIRED_FIELDS list.

Next, visit the admin.py file in your application folder and add the following to register your model:

Then add this line to say that CustomUser is what you’ll use to authenticate people.

Then migrate your database from your project root:

python manage.py makemigrations

python manage.py migrate

So, again, this was as far as my poster went. However, with great flexibility comes greater programming overhead on set up!

If you try to run an app with the code as it is now on your localhost, it will ostensibly work but you won’t be able to access the admin or add a user. The reason? You need to explicitly define this functionality via a user manager, and that’s where our CustomUserManager class comes in.

To create this functionality, you can import BaseUserManager from django.contrib.auth.models as shown on line 2, then sub >CustomAccountManager >create_user , create_superuser , and get_by_natural_key at a minimum, or you will encounter errors. If you want to create more specific permissions groups, this is where you should define those as well.

There are some other values you will have to set as well to make the user model work:

  • user.is_staff as shown on lines 8 & 16 → this controls access to the admin site.
  • user.is_superuser as shown on lines 9 & 17 → when True, the user has all available permissions
  • user.save() is saving the data from the form to the database


The get_by_natural_key method on line 21 should be set to whatever the >username , or whatever you’re replacing that value with — in our use case, this is email.

But we’re not quite done yet! We need to make some modifications to our CustomUser .

You might have noticed on line 2 in the screenshot above, we imported something called PermissionsMixin ; this is a really helpful model that prov >AbstractBaseUser and BaseUserManager or you will get errors. Then, add it to the arguments for your CustomUser model.

Note that we also need to add a get_short_name method, as Django expects a short name to be available for each user. This can be whatever field you want.

In addition, I’ve added a natural_key field which returns the email — as above, the credential the user needs to sign in — and a simple method to return the email as the string to represent the account.

Finally, Instantiation of the CustomAccountManager object on line 34 that we created a moment ago will enable us to access the methods we wrote for managing permissions and accessing data when we created the CustomAccountManager class.

Don’t forget to migrate your database when you’ve made all of these changes.

When you create a superuser (in terminal, python manage.py createsuperuser ), the screenshot on the left is what you’ll see when you sign and sign into the admin and create a user. Notice that we don’t have many of the standard Django user fields like first_name , last_name , etc.

This is a great option if you want to:

  • Use default fields from the Django User model
  • Control what the username variable will be with minimal overhead
  • Skip creating a custom user manager and leverage methods built into Django

However, this option does have some limitations around customizing the username , which we will see in a minute.

The first step is to write your model.

Notice that we are importing and sub >AbstractUser this time, but we don’t need the is_staff field because we’re effectively adding to the default User model which already has this attribute.

The USERNAME_FIELD resets the username to email, so that is required on sign in. The model already has an email field, but it needs to be added here as well to add the unique = True parameter . Another important note: the username field and password will be required, so they don’t need to go into the REQUIRED FIELDS list — in fact if you reset the USERNAME_FIELD the app will throw an error.

Add the AUTH_USER_MODEL variable to the project’s settings.py file, so the application knows what Users should look like.

Register your model in the project’s admin.py file to make it visible in the admin screen.

At this point, remember to run your migrations:

  • python manage.py makemigrations
  • python manage.py migrate

Then create a superuser ( python manage.py createsuperuser ) to test it. This is where you run into a problem if you want to use email as the username but not require an actual username when the person signs up: the source code for the AbstractUser model requires email , password AND username .

This means that:

  • If you don’t add username to REQUIRED_FIELDS when creating a superuser, you’ll get an error along the lines of TypeError: create_superuser() missing 1 required positional argument: ‘username’ because the AbstractUser model is expecting that argument, even though you’ve set USERNAME_FIELD = ’email’
  • If you try to create a user via a form in the browser that doesn’t include username, you’ll get an error like this: NOT NULL constraint failed: abstract_user_sample_customuser.username

There are a couple of options here, depending on your requirements:

  1. Use Option 1 and sub >AbstractBaseUser for your custom model instead. It does require more code, but it would be cleaner in some ways — for example, you could skip having a username entirely if it doesn’t make sense for your application
  2. Overr >models.py file, the same way you overrode the email parameters if you want to keep the field but don’t want to require it when a new user is created. Here’s a bare bones example that will wipe out the helper text, error message, etc. that are out of the box, but enables that field to be blank or set to null.
Цукерберг рекомендует:  Применяем CSS в зависимости от ориентации экрана

Because we’ve added username to REQUIRED_FIELDS on line 8, it will show up when you create a superuser in the command line, however you can specify fields in the forms.py file, so if you really don’t want end users adding a username on sign up, you can drop that completely and they can still complete the process, albeit with a blank username field in the database.

Make sure to run your migrations before testing!

When you sign into the admin panel and create a new user, you’ll see that — unlike in Option 1 — the default Django fields appear that weren’t explicitly in the model, as well as the zip_code field we added. Notice that Username appears but is not required.


This option doesn’t really match the original use case — to sign the user in with the email as a password — but it would make a lot of sense if you wanted to store user data that isn’t directly related to authentication in a way that’s still connected to the user model.

It’s pretty straightforward to implement. In the models.py file in your app, you’ll need to import the User model (shown on line 2) and then link it to the model with the OneToOneField method on line 5.

In this case, you don’t need to add anything to the settings.py file because you are still using the Django User model, however you do still need to register your model in admin.py as we saw in the other two examples.

The way that the User model and our CustomUser model are connected is very clear in the Admin. When you look at the admin for this version, you’ll see that Users and CustomUsers are separately listed.

Creating a user is the same as usual, but if you try to add a custom user, the admin will prompt you for the username of the record you want to attach our custom model to, and displays the zip_code field we added.

Resources for this post

While this post was long on detail (and thanks for sticking with it!), Django does have some pretty great features that can be confusing the first time you use them, so I hope this post was useful to you!

If you have any comments on this post, please leave them in the comments. Questions or requests on the examples can be added as Github issues .

AbstractUser Джанго полный пример

Я новичок в Django, и я пытался это в течение нескольких недель, но не мог найти способ, чтобы решить эту проблему.

Я хочу, чтобы хранить дополнительную информацию, как пользовательский мобильный номер, название банка, банковский счет. И хотите сохранить номер мобильного телефона в то время как пользователь регистрируется и хочет пользователю войти в систему с любым (номер мобильного телефона и пароль) или (адрес электронной почты и пароль).

Это моя UserProfile модель

И это мой forms.py

В моем settings.py я включил

admin.py моего приложения является

При добавлении пользователя от администратора Я получаю эту ошибку

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

При регистрации в регистрационной форме я также получаю эту ошибку

2 ответа

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

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

March 5, 2020, 10:35 a.m.

Стандартная джановская модель пользователя (User Model) содержит обязательное поле username. Во многих проектах есть необходимость использовать вместо него email пользователя. Сейчас мы разберем как это сделать.

ВАЖНО. Все последующие настройки необходимо выполнить в самом начале проекта, до запуска первой миграции. Переопределение полей в рабочем проекте более трудная задача и выходит за рамки данной статьи.

  1. Создадим новое приложение (не обязательно).
  2. Создадим собственную модель пользователя (User Model).
  3. Заменим дефолтную джанговскую модель собственной.
  4. Создадим собственный менеджер для новой модели.
  5. Зарегистрируем новую модель в админке.
  6. Произведем миграцию.
  7. Создадим суперпользователя.

Создаем новое приложение

python manage.py startapp YOUR_APP

Эта команда запускает создание нового приложения со следующей файловой структоруй:

YOUR_APP
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py

Добавляем приложение в файл settings.py


INSTALLED_APPS = [
# Default django installed apps
‘django.contrib.admin’,
.
.
‘YOUR_APP’,
]

Создаем собственную модель пользователя

Когда наше приложение создано и готово к использованию, можно перейти к определению модели User в файле models.py

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _

class User(AbstractUser):
«»»User model.»»»
username = None
email = models.EmailField(_(’email address’), unique=True)

USERNAME_FIELD = ’email’
REQUIRED_FIELDS = []

  • Расширили базовый клас модели пользователя Django
  • Удалили поле username
  • Сделали поле email уникальным и обязательным
  • Сообщили django, что необходимо использовать поле email в качестве основного для идентификации пользователя
  • Удали поле email из REQUIRED_FIELDS, т.к. этот параметр не должен включать переменные определенные в USERNAME_FIELD

Заменяем стандартную джанговскую модель User своей

Для этого добавим в settings.py параметр AUTH_USER_MODEL

## . некоторые другие настройки . ##

Создание собственного менеджера для новой модели пользователя

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

Расширим нашу модель пользователя в файле models.py

from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _

class UserManager(BaseUserManager):
«»»Define a model manager for User model with no username field.»»»

def _create_user(self, email, password, **extra_fields):
«»»Create and save a User with the given email and password.»»»
if not email:
raise ValueError(‘The given email must be set’)
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user

def create_user(self, email, password=None, **extra_fields):
«»»Create and save a regular User with the given email and password.»»»
extra_fields.setdefault(‘is_staff’, False)
extra_fields.setdefault(‘is_superuser’, False)
return self._create_user(email, password, **extra_fields)

def create_superuser(self, email, password, **extra_fields):
«»»Create and save a SuperUser with the given email and password.»»»
extra_fields.setdefault(‘is_staff’, True)
extra_fields.setdefault(‘is_superuser’, True)

if extra_fields.get(‘is_staff’) is not True:
raise ValueError(‘Superuser must have is_staff=True.’)
if extra_fields.get(‘is_superuser’) is not True:
raise ValueError(‘Superuser must have is_superuser=True.’)

return self._create_user(email, password, **extra_fields)

class User(AbstractUser):
«»»User model.»»»
.
.
objects = UserManager() ## это новое поле в User model. ##

Здесь мы:

  • Расширили стандартный User Manager
  • Определили 3 метода которые использует стандартная модель
  • Не используем username ни в одном из методов
  • Выполняем проверку на существование поля email при создании User
  • Назначили новый мэнеджер новой модели


Регистрируем новую модель в админке

При использовании стандартной админки необходимо подключить новое поле email для отображения в профиле User

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.utils.translation import ugettext_lazy as _
from .models import User

@admin.register(User)
class UserAdmin(DjangoUserAdmin):
«»»Define admin model for custom User model with no email field.»»»

  • Расширили исходный класс UserAdmin, предоставляемый администратором Django
  • Заменили username на email
  • Зарегистрировали наш новый класс для использования в админке новыой модели пользователя

Осталось выполнить миграцию

python manage.py migrate

И создать суперпользователя

python manage.py createsuperuser

Бонус

Если нам необходимо дополнить форму регистрации каким-либо новым полем (например phone), которое можно будет видеть внутри модели пользователя в админке, сделаем следующее.

Добавим в нашу модель User поле phone

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _

class User(AbstractUser):
«»»User model.»»»
username = None
email = models.EmailField(_(’email address’), unique=True)
phone = models.CharField(max_length=20, blank=True)

USERNAME_FIELD = ’email’
REQUIRED_FIELDS = []

Затем в поле Meta в форме регистрации в файле forms.py приложения которое отвечает за регистрацию (это не обязательно созданное нами приложение, поэтому поаккуратнее с импортами)

from django import forms
from django.contrib.auth.forms import UserCreationForm
from YOUR_APP.models import User

class Meta:
model = User
fields = ( ‘phone’ , ’email’, ‘password1’, ‘password2’,)

Теперь на странице регистрации у нас будет отображаться 4 поля: электронная почта, телефон, и 2 поля с паролем. А в админке внутри зарегистрированного пользователя появится поле phone.

Abstractuser — Django модель AbstractUser

418 просмотра

2 ответа

398 Репутация автора

Я пытался создать подкласс AbstractUser и застрял в ошибке при запуске миграции, и makemigrations говорит No changes detected

добавлено в settings.py:

Ответы (2)

плюса

3779 Репутация автора

Эта ошибка означает, что auth_group таблица не существует в вашей базе данных. Это означает, что вы не запускали файлы миграции Django (файлы python, описывающие структуру базы данных и ее изменения во времени).

Поскольку у вас есть свои собственные модели, вам сначала нужно создать для них файлы миграции, запустив их python manage.py makemigrations .

Затем запустите python manage.py migrate для запуска всех миграций (Django’s + yours), это создаст все таблицы базы данных (включая auth_croup ).

Прочитайте документ, чтобы больше узнать о миграции.

Автор: aumo Размещён: 01.05.2015 08:02

плюса

1 Репутация автора

при использовании AbstractUser могу ли я использовать встроенный рабочий процесс сброса пароля пользователя django, такой как сброс пароля, сброс пароля и т. д. . причина, по которой я спрашиваю, состоит в том, что я расширил пользовательскую модель, используя AbstractUser, но эти встроенные функции не работает, и я не получаю никакой ошибки, но он перенаправляет меня на страницу поиска, и в Интернете нет документации по этой проблеме:

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих