I am trying to extend the django-registration
register form according to:
Python/Django django-registration add an extra field
but I am getting:
current transaction is aborted, commands ignored until end of transaction block
In debugging I have added a breakpoint in the suggested regbackend.py
which suggests the broken code is at:
from crewcal.models import UserProfile
from forms import *
def user_created(sender, user, request, **kwargs):
form = CustomRegistrationForm(request.POST)
data = UserProfile(user=user)
import ipdb; ipdb.set_trace();
data.locality = form.data["locality"]
data.save()
from registration.signals import user_registered
user_registered.connect(user_created)
The problem (below), may have something to do with the way user profiles are created as defined in my models.py
:
def create_user_profile(sender, instance, created, raw, **kwargs):
if created and not raw:
print vars(instance)
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
User.profile = property(lambda u: UserProfile.\
objects.get_or_create(user=u)[0])
In the shell arising from the regbackend.py
breakpoint listed above, I can produce:
> /Users/project/app/regbackend.py(8)user_created()
7 import ipdb; ipdb.set_trace();
----> 8 data.locality = form.data["locality"]
9 data.save()
ipdb> data
<UserProfile: gub>
ipdb> vars(data)
{'user_id': 81, 'locality': None, '_user_cache': <User: gub>, '_state': <django.db.models.base.ModelState object at 0x103eb6990>, 'receive_email': True, 'id': None}
ipdb> form.data['locality']
u'BERLIN'
ipdb> data.locality = form.data['locality']
ipdb> vars(data)
{'user_id': 81, 'locality': u'BERLIN', '_user_cache': <User: gub>, '_state': <django.db.models.base.ModelState object at 0x103eb6990>, 'receive_email': True, 'id': None}
ipdb> data.save()
DEBUG (0.001) INSERT INTO "crewcal_userprofile" ("user_id", "receive_email", "locality") VALUES (81, true, 'BERLIN') RETURNING "crewcal_userprofile"."id"; args=(81, True, u'BERLIN')
*** InternalError: current transaction is aborted, commands ignored until end of transaction block
ipdb>
and in the verbose trace (incl. sql) up to that point, I get:
[16/May/2014 07:53:50] "GET /register/ HTTP/1.1" 200 163203
DEBUG (0.003) SELECT (1) AS "a" FROM "auth_user" WHERE UPPER("auth_user"."username"::text) = UPPER('gub') LIMIT 1; args=(u'gub',)
DEBUG (0.001) SELECT "django_site"."id", "django_site"."domain", "django_site"."name" FROM "django_site" WHERE "django_site"."id" = 1 ; args=(1,)
DEBUG (0.001) INSERT INTO "auth_user" ("username", "first_name", "last_name", "email", "password", "is_staff", "is_active", "is_superuser", "last_login", "date_joined") VALUES ('gub', '', '', '[email protected]', 'pbkdf2_sha256$10000$E2ZiaXLRtm0k$WrmqtRAhayt8w24Jpc8FYLTwRMbzDZIWhro/n/+hLpw=', false, true, false, '2014-05-16 07:54:00.398831', '2014-05-16 07:54:00.398831') RETURNING "auth_user"."id"; args=(u'gub', '', '', u'[email protected]', 'pbkdf2_sha256$10000$E2ZiaXLRtm0k$WrmqtRAhayt8w24Jpc8FYLTwRMbzDZIWhro/n/+hLpw=', False, True, False, u'2014-05-16 07:54:00.398831', u'2014-05-16 07:54:00.398831')
DEBUG (0.001) INSERT INTO "crewcal_userprofile" ("user_id", "receive_email", "locality") VALUES (81, true, NULL) RETURNING "crewcal_userprofile"."id"; args=(81, True, None)
DEBUG (0.001) INSERT INTO "crewcal_mycustomprofile" ("about_me", "facebook_id", "access_token", "facebook_name", "facebook_profile_url", "website_url", "blog_url", "date_of_birth", "gender", "raw_data", "image", "user_id") VALUES (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', 81) RETURNING "crewcal_mycustomprofile"."id"; args=(None, None, None, None, None, None, None, None, None, None, u'', 81)
DEBUG (0.001) SELECT (1) AS "a" FROM "auth_user" WHERE "auth_user"."id" = 81 LIMIT 1; args=(81,)
DEBUG (0.002) UPDATE "auth_user" SET "username" = 'gub', "first_name" = '', "last_name" = '', "email" = '[email protected]', "password" = 'pbkdf2_sha256$10000$E2ZiaXLRtm0k$WrmqtRAhayt8w24Jpc8FYLTwRMbzDZIWhro/n/+hLpw=', "is_staff" = false, "is_active" = false, "is_superuser" = false, "last_login" = '2014-05-16 07:54:00.398831', "date_joined" = '2014-05-16 07:54:00.398831' WHERE "auth_user"."id" = 81 ; args=(u'gub', '', '', u'[email protected]', 'pbkdf2_sha256$10000$E2ZiaXLRtm0k$WrmqtRAhayt8w24Jpc8FYLTwRMbzDZIWhro/n/+hLpw=', False, False, False, u'2014-05-16 07:54:00.398831', u'2014-05-16 07:54:00.398831', 81)
DEBUG (0.001) INSERT INTO "registration_registrationprofile" ("user_id", "activation_key") VALUES (81, 'f4ace49b34e503f271f252cb317bfbcc86be2238') RETURNING "registration_registrationprofile"."id"; args=(81, 'f4ace49b34e503f271f252cb317bfbcc86be2238')
I have tried feeding these commands in separately to dbshell, but I can't see the problem.
Any ideas?
When I face with something like adding special fields, or do any special action when creating an user I prefer to avoid overwrite User
model and do like:
Profile
with a OneToOneField to userProfile Model Example
class Profile(models.Model):
user = models.OneToOneField(User)
phone = models.CharField(max_length=255, blank=True, null=True, verbose_name='phone')
description = models.TextField(blank=True, verbose_name='descripction')
...
...
def not_first_log(self):
# Just a tiny example of a function to mark user as first-logged
self.first_log = False
self.save()
class Meta:
ordering = ['user']
verbose_name = 'user'
verbose_name_plural = 'users'
admin.py example
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
class ProfileInline(admin.StackedInline):
model = Profile
can_delete = False
filter_horizontal = ['filter fields'] # example: ['tlf', 'country',...]
verbose_name_plural = 'profiles'
fk_name = 'user'
class UserAdmin(UserAdmin):
inlines = (ProfileInline, )
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_filter = ('is_staff', 'is_superuser', 'is_active')
admin.site.unregister(User) # Unregister user to add new inline ProfileInline
admin.site.register(User, UserAdmin) # Register User with this inline profile
Create an user and attach a profile to him
# Create user
username = 'TestUser'
email = '[email protected]'
passw = '1234'
new_user = User.objects.create_user(username, email, passw)
# Create profile
phone = '654654654'
desc = 'Test user profile'
new_profile = Profile(user=new_user, phone = phone, description=desc)
new_profile.profile_role = new_u_prole
new_profile.user = new_user
# Save profile and user
new_profile.save()
new_profile.not_first_log()
new_user.save()
Now you'll have this Profile model attached to each user, and you could add the fields you wish to Profile Model, and for example if you make:
user = User.objects.get(id=1)
you can access to his profile doing:
user.profile
and to call any function
user.profile.function_name
You can also get the profile and do profile.user
I know you're trying to overwrite User
model but I'm pretty sure this is way is less complex and easy to manage, add new fields,actions or whatever you need
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With