Skip to content

4. Profile model, registration.

Dmitry edited this page Dec 7, 2018 · 3 revisions

Profile

./manage.py startapp account

One-to-one

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True)

models.py

from django.db import models
from django.conf import settings

class BaseProfile(models.Model):
    USER_TYPES = (
        (0, 'Customer'),
        (1, 'Admin'),
    )
    user = models.OneToOneField ( 
                                 settings.AUTH_USER_MODEL,\
                                 primary_key=True,\
                                 on_delete=models.CASCADE
                                )

    user_type = models.IntegerField(default=0, null=True, choices=USER_TYPES)
    name = models.CharField(max_length=200, blank=True, null=True)
    def __str__(self):
        return "{}".format(self.user.username)
    class Meta:
        abstract = True

class AdminProfile(models.Model):
    admin_email = models.CharField(max_length=100, blank=True, null=True)
    class Meta:
        abstract = True


class CustomerProfile(models.Model):
    phone = models.CharField(max_length=100, blank=True, null=True)
    address = models.CharField(max_length=250, blank=True, null=True)
    class Meta:
        abstract = True


class Profile(BaseProfile, AdminProfile, CustomerProfile):
    pass

Notes

  • All profile fields that belong to the class or its abstract bases classes must be nullable or with defaults

  • This approach might consume more database space per user but gives immense flexibility.

  • The active and inactive fields for a profile type need to be managed outside the model. Say, a form to edit the profile must show the appropriate fields based on the currently active user type.

Admin interface

from .models import Profile
from django.contrib.auth.models import User

class UserProfileInline(admin.StackedInline):
    model = Profile

class UserAdmin(admin.ModelAdmin):
    inlines = [UserProfileInline]

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

Form

from django.forms import ModelForm
from account.models import Profile
from django.contrib.auth.models import User

class CustomerRegForm(ModelForm):
    'Profile registration model form'
    class Meta:
        model = User
        fields = ['email', 'username', 'password']

Django form tweaks

pip install django-widget-tweaks

INSTALLED_APPS = [
...
'widget_tweaks',
...
]

Template

{% load widget_tweaks %}
{{ form.username|add_class:"form-control" }}

Saving form

if form.is_valid():  
    form.save()
    messages.success(request, 'Bingo !!!')

Show form only for not authenticated.

{% if not user.is_authenticated %}
    <form action="{% url 'registration' %}" method="POST">
                   
  {% endif %}

TODO

Fix load_users command.

Create the separate page of registration.

Move the login form down above registration.

Refactor code.

Clone this wiki locally