Как да добавите полета към Django User модел и да го покажете във формуляра за регистрация с 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-регистрация

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-registration repo, с приложена корекция за персонализирани потребителски модели от mrginglymus: https://bitbucket.org/ubernostrum/django-registration/pull-request/30/django-15-compatibility-with-custom-user/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 /06/28/ - person eagertoLearn; 21.03.2014
comment
Изглежда, че грешах: django-регистрацията не е съвместима с персонализирания потребителски модел. Имаше корекция преди много години, тя беше отхвърлена от автора на django-registration и без основателна причина, изглежда: bitbucket.org/ubernostrum/django-registration/pull-request/30/ - person frnhr; 21.03.2014
comment
@eagertoLearn Получих django-регистрация за работа с персонализиран потребителски модел, вижте актуализирания отговор - person frnhr; 21.03.2014
comment
Опитах го с вашия персонализиран потребителски модел, но имам няколко проблема, които поставих по-горе. моля вижте редакцията по-горе - person eagertoLearn; 22.03.2014
comment
@eagertoLearn Вижте актуализиран отговор. Това обаче е съвсем отделен въпрос. - person frnhr; 22.03.2014
comment
Преди всичко, големи благодарности!. имате страхотни познания по Django!. Мисля, че почти го накарах да работи, само няколко проблема. моля, помогнете ми да поправя това. Поставих в Редактиране 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 Model Мога ли да препоръчам книга: Танго с Django И винаги има официалните уроци - person frnhr; 25.03.2014

Най-добрият ви залог вероятно е да продължите и да създадете потребителски модел на потребител (можете да подкласирате django.contrib.auth.models.AbstractUser и да добавите каквито полета искате).

Що се отнася до обработката на множество модели в една форма, всъщност е доста лесно. Всъщност искате да използвате множество Forms, но да ги изобразите и двата в един и същ елемент <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