I noticed that the User model that Django provides does not have a Date of Birth Field
.
I do not want to write my own custom User class
just to include this attribute
. I am wondering if it is possible in some way to "attach" date of birth
to the User model
. If not what are the other simple options to make this work. I am also ok to save the contents of User Model
to a profile model
with additional date of birth
information.
But would my form
has to save both User and profile model
which I am confused as how this work.
EDIT 2: (After implementing frnhr's solution):
Two issues: No activation email
is sent out in the development server
. I tried default User model
with django-registration
and I see activation email
being sent out. but now, with the custom user model
, no activation email
is sent out.
when I login
as admin
, http://127.0.0.1:8000/admin/
, I see no User model
but only registration profiles
and Groups
. when I click registration profiles
, it does not show all the information about User
, but just username
and activation key
which is shown as already expired. Attached is a screenshot
. how to fix this?
In newer versions of Django, making your own custom User model is quite painless. See this answer for details: https://stackoverflow.com/a/16125609/236195
You might run into problems if you are using some older third-party apps which have model relationships hardcoded to auth.models.User
. Most of third-party apps which have ongoing development have probably switched already or will do so soon.
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 (add this line):
url(r'^accounts/', include('registration.backends.default.urls')),
myapp/admin.py (optionally):
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-registration
Get it from here: https://bitbucket.org/fhrzenjak/django-registration and put it in your project folder.
Disclaimer: this is my fork of the original django-registration repo, with applied patch for custom user models by mrginglymus: https://bitbucket.org/ubernostrum/django-registration/pull-request/30/django-15-compatibility-with-custom-user/diff
Django-registration-defaults is a collection of default templates from here: https://github.com/yourcelf/django-registration-defaults It's pip-installable
Well, this is a separate question, but ok here is how...
Create a MyRegistrationForm
form:
from registration.forms import RegistrationForm
class MyRegistrationForm(RegistrationForm):
age = forms.CharField(required=False)
In your urls.py add a line before django-registration include
. That will override whatever is in the include:
url(r'^accounts/register/$',
RegistrationView.as_view(form_class=MyRegistrationForm),
name='registration_register',
),
url(r'^accounts/', include('registration.backends.default.urls')),
Modify your custom user model to respond on user_registered
signal and save the additional data:
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)