Как добавить поля в модель пользователя Django и показать ее в регистрационной форме с помощью django-registration?

Я заметил, что модель пользователя, предоставляемая Django, не имеет Date of Birth Field. Я не хочу писать свой custom User class только для того, чтобы включить этот attribute. Мне интересно, можно ли как-то "привязать" date of birth к User model. Если нет, то каковы другие простые варианты, чтобы сделать эту работу. Я также могу сохранить содержимое User Model в profile model с дополнительной информацией date of birth.

Но мой form должен сохранить оба User and profile model, что меня смущает, как это работает.

РЕДАКТИРОВАТЬ 2: (после реализации решения frnhr):

Две проблемы: activation email не отправляется в development server. Я попробовал default User model с django-registration и вижу, что activation email отправляется. но теперь, с custom user model, отправляется no activation email.

когда я login как admin, http://127.0.0.1:8000/admin/, я не вижу User model, а только registration profiles и Groups. когда я нажимаю registration profiles, отображается не вся информация о User, а только username и activation key, срок действия которых уже истек. Прилагается файл screenshot. как это исправить? введите здесь описание изображения

введите здесь описание изображения


person eagertoLearn    schedule 21.03.2014    source источник


Ответы (2)


В более новых версиях Django создание собственной пользовательской модели пользователя довольно просто. Подробнее см. в этом ответе: https://stackoverflow.com/a/16125609/236195

Вы можете столкнуться с проблемами, если используете некоторые старые сторонние приложения, отношения моделей которых жестко закодированы в auth.models.User. Большинство сторонних приложений, которые находятся в стадии разработки, вероятно, уже перешли или сделают это в ближайшее время.


Изменить - заставить его работать с django-registration

myapp/models.py:

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

class CustomUser(AbstractUser):
    age = models.PositiveIntegerField(_("age"), null=True)  # this field is added to default User model

settings.py:

INSTALLED_APPS = (
    # ...

    'registration_defaults',
    'registration',

    'myapp',
)

# ...

AUTH_USER_MODEL = "myapp.CustomUser"
ACCOUNT_ACTIVATION_DAYS = 2  # or something

urls.py (добавьте эту строку):

   url(r'^accounts/', include('registration.backends.default.urls')),

myapp/admin.py (необязательно):

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

from .models import CustomUser


class CustomUserAdmin(UserAdmin):
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email', 'age')}),  # added "age" field
        (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
                                       'groups', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )


admin.site.register(CustomUser, CustomUserAdmin)

django-регистрация

Получите его отсюда: https://bitbucket.org/fhrzenjak/django-registration и поместите это в папке вашего проекта.

Отказ от ответственности: это моя вилка оригинального репозитория регистрации django с примененным патчем для пользовательских моделей от mrginglymus: https://bitbucket.org/ubernostrum/django-registration/pull-request/30/django-15-совместимость-с-настраиваемым-пользователем/diff

Django-registration-defaults — это набор шаблонов по умолчанию отсюда: https://github.com/yourcelf/django-registration-defaults Его можно установить с помощью pip

РЕДАКТИРОВАТЬ 2 - принять настраиваемое поле при регистрации

Ну это отдельный вопрос, но ладно вот как...

Создайте форму MyRegistrationForm:

from registration.forms import RegistrationForm

class MyRegistrationForm(RegistrationForm):
    age = forms.CharField(required=False)

В вашем urls.py добавьте строку перед django-registration include. Это переопределит все, что включено:

url(r'^accounts/register/$',
        RegistrationView.as_view(form_class=MyRegistrationForm),
        name='registration_register',
    ),
url(r'^accounts/', include('registration.backends.default.urls')),

Измените пользовательскую модель пользователя, чтобы она реагировала на сигнал user_registered, и сохраните дополнительные данные:

class CustomUser(AbstractUser):
    age = models.PositiveIntegerField(_("age"), null=True)

    @classmethod
    def user_created(cls, sender, user, request, **kwargs):
        from myapp.forms import MyRegistrationForm
        form = MyRegistrationForm(request.POST)
        user.age = form.data.get('age', None)
        user.save()
        pass

from registration.signals import user_registered
user_registered.connect(CustomUser.user_created)
person frnhr    schedule 21.03.2014
comment
Спасибо за ответ. Я действительно хочу использовать стороннее приложение. django-registration.. Он утверждает, что предоставляет способ расширения пользовательской модели, но это не тривиально. - person eagertoLearn; 21.03.2014
comment
django-registration совместим с пользовательскими моделями - person frnhr; 21.03.2014
comment
Это то, что он утверждает, у вас есть фрагмент кода, как вы заставили его работать, или какие-то ссылки, я следил за многими сообщениями, но, на мой взгляд, это не просто. Эта ссылка утверждает, что это просто. но на самом деле это не так. johnparsons.net/index.php/2013 /28/06/ - person eagertoLearn; 21.03.2014
comment
Похоже, я ошибся: django-registration не совместим с пользовательской моделью пользователя. Давным-давно был патч, он был отклонен автором django-registration, и, казалось бы, зря: bitbucket.org/ubernostrum/django-registration/pull-request/30/ - person frnhr; 21.03.2014
comment
@eagertoLearn Я получил django-registration для работы с пользовательской моделью пользователя, см. обновленный ответ. - person frnhr; 21.03.2014
comment
Я попробовал это с вашей пользовательской моделью пользователя, но у меня есть несколько проблем, которые я вставил выше. пожалуйста, смотрите редактирование выше - person eagertoLearn; 22.03.2014
comment
@eagertoLearn Смотрите обновленный ответ. Хотя это уже совсем отдельный вопрос. - person frnhr; 22.03.2014
comment
Прежде всего, большое спасибо вам!. у вас отличные знания в Джанго!. Я думаю, что у меня почти получилось, только пара вопросов. пожалуйста, помогите мне исправить это. Я вставил в Edit 2 выше. Большое спасибо - person eagertoLearn; 23.03.2014
comment
У меня есть мой код (который точно соответствует вашим указаниям) доступен здесь; github.com/sridhar1982/djangoRegistration_CustomUser, пожалуйста, помогите мне решить эту проблему! - person eagertoLearn; 24.03.2014
comment
См. приведенный выше раздел myapp/admin.py (необязательно): именно так вы добавляете пользовательскую модель пользователя в admin. - person frnhr; 24.03.2014
comment
Кстати, регистрационные профили — это что-то еще (не содержащие ваши пользовательские поля). - person frnhr; 24.03.2014
comment
Я получаю эту ошибку для сброса пароля Reverse for 'password_reset_complete' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: [], в репозитории github, который я дал выше. пожалуйста, помогите исправить это.. - person eagertoLearn; 24.03.2014
comment
на этапе разработки я делал python -m smtpd -n -c DebuggingServer localhost:1025 на terminal, а activation emails отправлял на этот terminal. но теперь я вижу (с вашими изменениями и вашим git repo), activation email отправляется на тот же terminal, где я запускаю ./manage.py runserver. это почему? - person eagertoLearn; 24.03.2014
comment
Бэкенд электронной почты консоли только для разработчиков. Это быстрый способ работать с электронной почтой локально без необходимости настраивать почтовый сервер на вашем устройстве разработчика. Ваше решение кажется вполне приемлемым, но в этом случае используйте бэкенд электронной почты по умолчанию в вашем settings.py (т.е. удалите строку EMAIL_BACKEND = ... из setting.py). - person frnhr; 24.03.2014
comment
Спасибо за ответ. В приведенном выше классе CustomUser есть только поле age, но я вижу в admin page, в нем есть fields, такие как username, email и т. д. Откуда они берутся? Я определил свой собственный CustomUser model, в котором есть только field, верно? так зачем эти лишние поля? - person eagertoLearn; 25.03.2014
comment
Унаследовано от django.contrib.auth.models.AbstractUser (если я правильно понял). Наследование модели Django Могу ли я порекомендовать книгу: Tango With Django И всегда есть официальные руководства - person frnhr; 25.03.2014

Лучше всего, вероятно, пойти дальше и создать пользовательскую модель пользователя (вы можете создать подкласс django.contrib.auth.models.AbstractUser и добавить любые поля, которые хотите).

Что касается обработки нескольких моделей в одной форме, на самом деле это довольно просто. На самом деле вы хотите использовать несколько Form, но визуализировать их оба в одном и том же элементе <form> и обрабатывать их отдельно в представлении.

Другой подход состоит в том, чтобы просто создать один Form (вероятно, не ModelForm), который содержит все нужные вам поля. Затем напишите в форме метод save, который создает/обновляет соответствующие модели. Это делает ваше представление и код шаблона проще, чем описанный выше подход.

В качестве примера, вот класс формы, который позволяет существующему пользователю изменить свой адрес электронной почты и дату рождения. Обратите внимание, что вы передаете вошедший в систему User из своего представления при вызове save():

class UserEditForm(forms.Form):
    email = forms.EmailField()
    date_of_birth = forms.DateField()

    def save(self, user):
        user.email = self.cleaned_data['email']
        user.save()
        user.userprofile.date_of_birth = self.cleaned_data['date_of_birth']
        user.userprofile.save()

Обратите внимание, что это предполагает, что у вас есть модель UserProfile, которая имеет поле "один к одному" для User.

person Chris Lawlor    schedule 21.03.2014
comment
Я хочу интегрировать свою пользовательскую модель с приложением django-registration, что не так просто. Я следил за этим сообщением: http://johnparsons.net/index.php/2013/06/28/creating-profiles-with-django-registration/, но он вообще не обновляет модель пользователя. - person eagertoLearn; 21.03.2014
comment
Основываясь на моем опыте работы с django-registration для работы с пользовательскими моделями около года назад, я бы сказал, что вам, вероятно, лучше написать собственный рабочий процесс регистрации. - person Chris Lawlor; 21.03.2014