Extending the user model?

1,499 views
Skip to first unread message

Mark McKinlay

unread,
Jul 15, 2014, 3:38:57 AM7/15/14
to wag...@googlegroups.com
I've been dipping my toe into Wagtail a bit and was wondering if its possible to extend the base usermodel in the same way you would with standard django.

I have been looking around a bit and whilst I can see its possible with vanilla django I am not sure with wagtail. I dont want to keep running down an alley if its gonna be a dead end :D

so far I have a model as follows :

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




class member(models.Model):
    identifier
= models.CharField(max_length=40, unique=True)
    user
= models.OneToOneField(User)
    middle_names
= models.CharField(max_length=100)


    date_of_birth
= models.DateField()


    sex
= models.CharField(max_length=6)


    phone_number
= models.CharField(max_length=15)


    address1
= models.CharField(max_length=50)
    address2
= models.CharField(max_length=50)
    town
= models.CharField(max_length=50)
    county
= models.CharField(max_length=50)
    postcode
= models.CharField(max_length=15)


    website
= models.URLField()
    facebook
= models.URLField()
    twitter
= models.URLField()
    google_plus
= models.URLField()


    is_active
= models.BooleanField()


Thanks for any help

Chris Moradi

unread,
Jul 15, 2014, 1:27:27 PM7/15/14
to wag...@googlegroups.com
I'm fairly new to Django and Wagtail, but I've been building a site with a profile extension to a User, and it's working fine. Here are a couple of small things that you might want to look into:
  1. I've read that it's better to allow for a custom user model if this member model will be reused:
    user = models.OneToOneField(settings.AUTH_USER_MODEL)
      instead of
    user = models.OneToOneField(User)
  2. You'll probably want to override __unicode__() (For Python 2.x) or __str__() (Python 3.x). Maybe you just left that out of the example code.
-Chris

Mark McKinlay

unread,
Jul 16, 2014, 5:24:03 AM7/16/14
to wag...@googlegroups.com
HI Chris,

Could you share the code you've done for the profile extension?

I feel like I'm going around in circles at times :D

Chris Moradi

unread,
Jul 18, 2014, 12:27:42 PM7/18/14
to wag...@googlegroups.com
Hi Mark,

# in accounts/model.py
from django.db import models
from django.conf import settings
from partners.models import Partner

class Profile(models.Model):
   # This line is required. Links UserProfile to a User model instance.
   user = models.OneToOneField(settings.AUTH_USER_MODEL)

    # The additional attributes we wish to include.
   slate_id = models.CharField(max_length=9, blank=True, default='')
   slate_guid = models.CharField(max_length=36, blank=True, default='')
   chapter = models.ForeignKey(Partner)
   is_liaison = models.BooleanField(default=False)

    # Override the __unicode__() method to return out something meaningful!
   def __unicode__(self):
       name = self.user.first_name if self.user.first_name else self.user.username
       chapter = self.chapter.short_name if self.chapter else 'no chapter'
       return '{} ({})'.format(name, chapter)
Enter code here...


Where you create users, you should also create a Profile for them. Here's how I'm doing it, but this may not be following best practices:

        profile, pcreated = Profile.objects.get_or_create(user=user)
        profile.slate_id = slate_id
        profile.slate_guid = attributes.get('person', '')
        chapter_full_name = slate_profile.get('chapter', '')
        profile.chapter = Partner.objects.get(full_name=chapter_full_name)
        profile.save()


You can register your Profile with the Django admin by creating an admin.py file where your profile model lives.

#accounts/admin.py

from .models import Profile
from django.contrib import admin

admin.site.register(Profile)

Using the wagtail demo site, the standard Django admin is accessible at http://mydomain.com/django-admin/

Hope this is helpful.

-Chris

Elliot

unread,
Aug 17, 2014, 9:25:57 PM8/17/14
to wag...@googlegroups.com
Hi,

Thought I would just expand on this answer a little with a full custom user. It's not a generic case, so some parts will need to be changed for use by others. This isn't a tutorial as there are already lots out there on custom django user models, but if you notice something wrong, missing or better, feel free to let me know and I can change it. 

This custom user uses an email address as the unique field, for it to play nice with the wagtail admin 'username' field is included in the model (which is a copy of 'email' field).

The file structure as follows:

my_app
    - templates
        - my_app
            ...
        - wagtailadmin
            - account
                - account.html
                - (template extensions e.g. account/my_other_preference)
            - login.html
        - wagtailusers
            - create.html
            - edit.html
        base.html
    - __init__.py
    - admin.py
    - forms.py
    - models.py
    - views.py
    - wagtail_hooks.py

First up add AUTH_USER_MODEL = 'my_app.MyUser' to your settings.py (or base.py whatever you're using)

models.py

from django.db import models
from datetime import date
from dateutil.relativedelta import relativedelta
from django_resized import ResizedImageField
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser, PermissionsMixin
)



class MyUserManager(BaseUserManager):
    def create_user(
        self,
        email,
        first_name=None,
        last_name=None,
        password=None,
        address=None,
        city=None,
        **extra_fields

    ):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
            first_name=first_name,
            last_name=last_name,
            address=address,
            city=city,
            **extra_fields
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(
        self,
        email,
        password,
        first_name=None,
        last_name=None,
        address=None,
        city=None,
        **extra_fields
    ):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(
            email,
            first_name=first_name,
            last_name=last_name,
            password=password,
            address=address,
            city=city,
            **extra_fields
        )
        user.is_superuser = True
        user.is_staff = True
        user.save(using=self._db)
        return user


class MyUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    username = models.EmailField(verbose_name='Username', max_length=255, null=True)
    first_name = models.CharField('First name', max_length=255)
    last_name = models.CharField("last name", max_length=255)
    profile_pic = ResizedImageField('Profile picture', use_thumbnail_aspect_ratio=False, upload_to='profile', null=True, blank=True)
    company = models.CharField('Company name', max_length=100, null=True, blank=True)
    employee_number = models.PositiveIntegerField('Number of employees', null=True, blank=True)
    company_types = (
        ('',''),
        ('Corporate', 'Corporate'),
        ('Production', 'Production'),
        ('Sponsorship', 'Sponsorship'),
        ('Technical', 'Technical'),
    )
    company_type = models.CharField('Type of company', max_length=20, choices=company_types, null=True, blank=True)
    join_date = models.DateField('Date joined', default=date.today())
    membership_expiration = models.DateField('Membership expiration', default=date.today() + relativedelta(months=+1))
    membership_choices = (
        ('',''),
        ('temporary', 'temporary'),
        ('full', 'full'),
        ('super', 'super'),
    )
    membership_type = models.CharField('Membership type', max_length=20,
choices=membership_choices, default='temporary',)
    address = models.CharField('Address', max_length=255)
    suburb = models.CharField('Suburb', max_length=255, null=True, blank=True)
    city = models.CharField('City', max_length=255)
    is_staff = models.BooleanField('staff status', default=False)
    is_active = models.BooleanField('active', default=True)
    is_admin = models.BooleanField('admin', default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name', 'address', 'suburb', 'city']

    def get_full_name(self):
        # The user is identified by their email address
        return "%s %s" % (self.first_name, self.last_name)

    def get_short_name(self):
        # The user is identified by their email address
        return self.first_name

    def __unicode__(self):              # __unicode__ on Python 2
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True


admin.py

This is setting up the django-admin i.e. default django admin

from django.contrib import admin
from models import *
from forms import *
from django.contrib.auth.admin import UserAdmin


class MyUserAdmin(UserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('email', 'first_name', 'last_name', 'is_superuser')
    list_filter = ('is_superuser', 'is_staff', 'is_active')
    readonly_fields = ('join_date', 'username')
    fieldsets = (
        (None, {'fields': ('email', 'password', 'username')}),
        ('Personal info', {'fields': ('first_name', 'last_name', 'profile_pic', 'address', 'suburb', 'city')}),
        ('Company info', {'fields': ('company', 'company_type', 'employee_number')}),
        ('Membership', {'fields': ('join_date', 'membership_expiration', 'membership_type')}),
        ('Permissions', {'fields': ('is_superuser', 'is_staff', 'is_active')}),
        ('Groups', {'fields': ('groups',)}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'first_name', 'last_name', 'address', 'suburb', 'city', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
admin.site.register(MyUser, MyUserAdmin)

wagtail_hooks.py

This is where you would want to put extra url's like 'account/my_other_preferences' and the views etc that go with them.

from django.conf.urls import url
from wagtail.wagtailcore import hooks
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import permission_required
from django.contrib import messages
from django.utils.translation import ugettext as _
from wagtail.wagtailcore.compat import AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME
from forms import *

# Typically we would check the permission 'auth.change_user' for user
# management actions, but this may vary according to the AUTH_USER_MODEL
# setting
change_user_perm = "{0}.change_{1}".format(AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME.lower())


@permission_required(change_user_perm)
def create(request):
    if request.POST:
        form = UserCreationForm(request.POST, request.FILES)
        if form.is_valid():
            user = form.save(commit=False)
            try:
                user.profile_pic = request.FILES['profile_pic']
            except Exception:
                pass
            user.save()
            messages.success(request, _("User '{0}' created.").format(user))
            return redirect('wagtailusers_index')
        else:
            messages.error(request, _("The user could not be created due to errors.") )
    else:
        form = UserCreationForm()

    return render(request, 'wagtailusers/create.html', {
        'form': form,
    })


@permission_required(change_user_perm)
def edit(request, user_id):
    user = get_object_or_404(MyUser, id=user_id)
    if request.POST:
        form = UserChangeForm(request.POST, request.FILES, instance=user)
        if form.is_valid():
            print form.cleaned_data, request.FILES
            user = form.save(commit=False)
            user.groups = form.cleaned_data['groups']
            try:
                user.profile_pic = request.FILES['profile_pic']
            except Exception:
                pass
            user.save()
            messages.success(request, _("User '{0}' updated.").format(user))
            return redirect('wagtailusers_index')
        else:
            messages.error(request, _("The user could not be saved due to errors."))
    else:
        form = UserChangeForm(instance=user)

    return render(request, 'wagtailusers/edit.html', {
        'user': user,
        'form': form,
    })


@hooks.register('register_admin_urls')
def url_account():
    return [
        url(r'^users/(\d+)/$', edit, name='wagtailusers_edit'),
        url(r'^users/new/$', create, name='wagtailusers_create'),
    ]

forms.py

from models import *
from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField


class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = MyUser
        fields = (
            'email',
            'first_name',
            'last_name',
            'profile_pic',
            'company',
            'employee_number',
            'company_type',
            'membership_type',
            'address',
            'suburb',
            'city',
            'is_active',
            'is_superuser',
            'is_staff',
            'groups'
        )
        widgets = {
            'groups': forms.CheckboxSelectMultiple
        }

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        user.username = self.cleaned_data['email']
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField()
    password1 = forms.CharField(label="Password", required=False,
        widget=forms.PasswordInput)
    password2 = forms.CharField(label="Password confirmation", required=False,
        widget=forms.PasswordInput,
        help_text="Enter the same password as above, for verification.")

    class Meta:
        model = MyUser
        fields = (
            'email',
            'password',
            'first_name',
            'last_name',
            'profile_pic',
            'company',
            'employee_number',
            'company_type',
            'membership_expiration',
            'membership_type',
            'address',
            'suburb',
            'city',
            'is_active',
            'is_superuser',
            'is_staff',
            'groups'
        )
        widgets = {
            'groups': forms.CheckboxSelectMultiple
        }

    def clean(self):
        cleaned_data = super(UserChangeForm, self).clean()
        return cleaned_data

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]

    def clean_password2(self):
    # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserChangeForm, self).save(commit=False)
        if self.cleaned_data['password1']:
            user.set_password(self.cleaned_data['password1'])
        user.username = self.cleaned_data['email']
        if commit:
            user.save()
        return user

create.html

{% extends "wagtailadmin/base.html" %}
{% load wagtailimages_tags %}
{% load i18n %}
{% block titletag %}{% trans "Add user" %}{% endblock %}
{% block bodyclass %}menu-users{% endblock %}
{% block content %}

    {% trans "Add user" as add_user_str %}
    {% include "wagtailadmin/shared/header.html" with title=add_user_str merged=1 tabbed=1 icon="user" %}

    <ul class="tab-nav merged">
        <li class="active"><a href="#account">{% trans "Account" %}</a></li>
        <li><a href="#company">{% trans "Company" %}</a></li>
        <li><a href="#roles">{% trans "Roles" %}</a></li>
        <li><a href="#membership">{% trans "Membership" %}</a></li>
    </ul>
    <form action="{% url 'wagtailusers_create' %}" method="POST" enctype="multipart/form-data">
        <div class="tab-content">
            {% csrf_token %}
            <section id="account" class="active nice-padding">
                <ul class="fields">
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.email %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.first_name %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.last_name %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.profile_pic %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.address %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.suburb %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.city %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.password1 %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.password2 %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_active %}

                    <li><a href="#company" class="button lowpriority tab-toggle icon icon-arrow-right-after" />{% trans "Company" %}</a></li>
                </ul>
            </section>
             <section id="company" class="nice-padding">
                <ul class="fields">
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.company %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.company_type %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.employee_number %}
                    <li><a href="#roles" class="button lowpriority tab-toggle icon icon-arrow-right-after" />{% trans "Roles" %}</a></li>
                </ul>
            </section>
            <section id="roles" class="nice-padding">
                <ul class="fields">
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_admin %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_staff %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.groups %}
                    <li><a href="#membership" class="button lowpriority tab-toggle icon icon-arrow-right-after" />{% trans "Membership" %}</a></li>
                </ul>
            </section>
            <section id="membership" class="nice-padding">
                <ul class="fields">

                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.membership_type %}
                    <li><input type="submit" value="{% trans 'Save' %}" /></li>
                </ul>
            </section>
        </div>
    </form>
    <style>
        .image_form_field .input label {
            float: initial;
        }
    </style>
{% endblock %}

edit.html

pretty similar to create.html

{% extends "wagtailadmin/base.html" %}
{% load wagtailimages_tags %}
{% load i18n %}
{% block titletag %}{% trans "Editing" %} {{ user.username }}{% endblock %}
{% block bodyclass %}menu-users{% endblock %}
{% block content %}

    {% trans "Editing" as editing_str %}
    {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=user.username merged=1 tabbed=1 icon="user" %}

    <ul class="tab-nav merged">
        <li class="active"><a href="#account">{% trans "Account" %}</a></li>
        <li><a href="#company">{% trans "Company" %}</a></li>
        <li><a href="#roles">{% trans "Roles" %}</a></li>
        <li><a href="#membership">{% trans "Membership" %}</a></li>
    </ul>

    <form action="{% url 'wagtailusers_edit' user.id %}" method="POST" enctype="multipart/form-data">
        <div class="tab-content">
            {% csrf_token %}

            <section id="account" class="active nice-padding">
                <ul class="fields">
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.email %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.first_name %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.last_name %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.profile_pic %}
                    <li>
                        {# label is just for formatting reasons #}
                        <label for=""></label>
                        <img src="{{MEDIA_URL}}{{user.profile_pic}}" alt="" style='max-width: 80px; max-height:80px; border: none;'>
                    </li>
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.address %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.suburb %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.city %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.password1 %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.password2 %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_active %}

                    <li><input type="submit" value="{% trans 'Save' %}" /></li>
                </ul>
            </section>
             <section id="company" class="nice-padding">
                <ul class="fields">
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.company %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.company_type %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.employee_number %}
                    <li><input type="submit" value="{% trans 'Save' %}" /></li>
                </ul>
            </section>
            <section id="roles" class="nice-padding">
                <ul class="fields">
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_superuser %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.is_staff %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.groups %}
                    <li><input type="submit" value="{% trans 'Save' %}" /></li>
                </ul>
            </section>
            <section id="membership" class="nice-padding">
                <ul class="fields">

                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.membership_expiration %}
                    {% include "wagtailadmin/shared/field_as_li.html" with field=form.membership_type %}
                    <li><input type="submit" value="{% trans 'Save' %}" /></li>
                </ul>
            </section>
        </div>
    </form>
    {# style is to sort out the clear label and the clear box from being serparated when rendered #}
    <style>
        .image_form_field .input label {
            float: initial;
        }
    </style>
{% endblock %}


You will want to add the following line into you urls.py:

urlpatterns += static(settings.MEDIA_URL + 'profile/', document_root=os.path.join(settings.MEDIA_ROOT, 'profile'))

Then I image you would use something similar to the following couple of lines in your urls.py to point to your views you would use for your custom user in the site.

url(r'^membership/login/$', 'my_app.views.membership_login', name='membership_login'),
url(r'^membership/sign-up/$', 'my_app.views.membership_signup', name='membership_sign_up'),
url(r'^membership/logout/$', 'my_app.views.membership_logout', name='membership_logout'),
url(r'^membership/remove/$', 'my_app.views.membership_remove', name='membership_remove'),
url(r'^membership/change-password/$', 'my_app.views.membership_change_password', name='membership_change_password'),
url(r'^membership/reset-password/$', 'my_app.views.membership_reset_password', name='membership_reset_password'),

If you were to copy and paste all of this don't forget to pip install django-resized. 

Just for sake of completeness here is the account.html. But if you extend it here don't forget to add the url and functions to wagtail_hooks.py.

{% extends "wagtailadmin/base.html" %}
{% load i18n %}

{% block titletag %}{% trans "Account" %}{% endblock %}
{% block content %}
    {% trans "Account" as account_str %}
    {% include "wagtailadmin/shared/header.html" with title=account_str %}

    <div class="nice-padding">
        <ul class="listing">
            <li class="row row-flush">
                <div class="col6">
                    <a href="http://gravatar.com" class="button button-primary">{% trans "Set gravatar" %}</a>
                </div>

                <small class="col6">
                    {% trans "Your avatar image is provided by Gravatar and is connected to your email address. With a Gravatar account you can set an avatar for any number of other email addresses you use." %}

                </small>

            </li>
            {% if show_change_password %}
                <li class="row row-flush">
                    <div class="col6">
                        <a href="{% url 'wagtailadmin_account_change_password' %}" class="button button-primary">{% trans "Change password" %}</a>
                    </div>

                    <small class="col6">
                        {% trans "Change the password you use to log in." %}
                    </small>
                </li>
            {% endif %}
            {% if show_notification_preferences %}
                <li class="row row-flush">
                    <div class="col6">
                        <a href="{% url 'wagtailadmin_account_notification_preferences' %}" class="button button-primary">{% trans "Notification preferences" %}</a>
                    </div>

                    <small class="col6">
                        {% trans "Choose which email notifications to receive." %}
                    </small>
                </li>
            {% endif %}
           
{# Here is where you would probably add in your own list items if you were to extend this page e.g. #}
            {#
            
{% if my_other_preferences %}
                <li class="row row-flush">
                    <div class="col6">
                        <a href="{% url 'my_other_preferences_template' %}" class="button button-primary">{% trans "My other preferences" %}</a>
                    </div>

                    <small class="col6">
                        {% trans "Choose which preferences to set." %}
                    </small>
                </li>
            {% endif %}
            #}

        </ul>
    </div>
{% endblock %}



I hope this helped.

Elliot

Elliot

unread,
Aug 17, 2014, 10:41:25 PM8/17/14
to wag...@googlegroups.com
oh and my_app needs to come before wagtail apps in INSTALLED_APPS

JJ Argyle

unread,
Nov 29, 2015, 5:46:48 AM11/29/15
to Wagtail support
I've gotten pretty far getting your very helpful User Model bits working, but i'm hitting a stumbling block getting it to take my POST data.

It keeps saying that create_user() missing 1 required positional argument: 'self'

def create_user(self, email, first_name=None, last_name=None, password=None, address=None, city=None, **extra_fields)

I know it wants a user object, but I just can't fathom how to pass one from the views.py

if request.method == 'POST':
     form = UserCreationForm(request.POST)
     if form.is_valid():
          user = MyUserManager.create_user(
               #self goes here
               password = form.cleaned_data['password1'],
               email = form.cleaned_data['email'],
   )
# More code down here


Elliot

unread,
Nov 29, 2015, 12:19:53 PM11/29/15
to Wagtail support
Hi,

It looks to me like the way you're trying to call it is the problem. UserCreationForm(request.POST) should be holding the password and email already. Try

if request.method == 'POST':
     form = UserCreationForm(request.POST)
     if form.is_valid():
user = form.save(commit=False)
# whatever else you want to do before saving i.e.
# user.is_magician = True
user.save() 

 
Wagtail has changed a bit with upgrades since this. Maybe I'll write another example sometime.


JJ Argyle

unread,
Nov 29, 2015, 2:00:14 PM11/29/15
to Wagtail support
Success!

Thanks Elliot. I was scratching my head for hours last night. 

For anyone else that needs a view, this is what I got.

@csrf_protect
def signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
# whatever else you want to do before saving i.e.
# user.is_magician = True
user.save() 

return HttpResponseRedirect('/register/success/')
else:
template = loader.get_template('registration/register.html')
form = UserCreationForm()
context = RequestContext(request, {'form': form})

return HttpResponse(template.render(context))

def register_success(request):
    return render_to_response(
    'registration/success.html',
    )


 
Reply all
Reply to author
Forward
0 new messages