Registration extend nightmare

93 views
Skip to first unread message

Matt Guy

unread,
May 30, 2014, 10:26:04 AM5/30/14
to django...@googlegroups.com
I am trying to add an extra user profile registration field using registration. Should be so simple but this is bringing me to the edge.



Basically I want to add a 'city' field to the registration form. I have tried many solutions, but am currently attempting versions of this: http://dmitko.ru/django-registration-form-custom-field/

In my app I have a backend regbackend.py relying on django-registration's signals:

______________________________________________

from forms import *
from models import UserProfile
from django.db.models.signals import post_save


def user_created(sender, user, request, **kwargs):
new_user = RegistrationProfile.objects.get(us)
    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
import crewcal.models
user_registered.connect(user_created)
______________________________________________


The related models:

______________________________________________

class Locality(models.Model):
    locality = models.CharField(max_length=50)

    def __unicode__(self):
        return self.locality

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    event_commitments = models.ManyToManyField(Event,
        null=True, blank=True)
    receive_email = models.BooleanField(default=True)
    locality = models.ManyToManyField(Locality,
        null=True, blank=True)

    def __unicode__(self):
        return self.user.username

    @property
    def url(self):
        return self.get_absolute_url()

    @models.permalink
    def get_absolute_url(self):
        return ('crewcal.views.profile', [str(self.id)])

userprofile_created = django.dispatch.Signal(providing_args=["user", "request"])

def create_user_profile(sender, instance, created, raw, **kwargs):
    if created and not raw:
        UserProfile.objects.create(user=instance)
        profile = UserProfile.objects.get(user=instance)
        userprofile_created.send(sender=UserProfile,
            user=instance, request=request)

post_save.connect(create_user_profile, sender=User)

User.profile = property(lambda u: UserProfile.\
     objects.get_or_create(user=u)[0])
______________________________________________


I get a mixture of errors (dependent on the slight tweaks I make), such as:

current transaction is aborted, commands ignored until end of transaction block

and:

"<UserProfile: ppokkutt>" needs to have a value for field "userprofile" before this many-to-many relationship can be used.

This last message suggests to me that the UserProfile is not saved before the signal is sent (from the django-registration plugin) to the custom backend (regbackend.py above) which attempts to update that non-existent entry with the locality. Here is the relevant code from django-registration views.py:
______________________________________________

    def register(self, request, **cleaned_data):

        """

        Given a username, email address and password, register a new

        user account, which will initially be inactive.


        Along with the new ``User`` object, a new

        ``registration.models.RegistrationProfile`` will be created,

        tied to that ``User``, containing the activation key which

        will be used for this account.


        After the ``User`` and ``RegistrationProfile`` are created and the activation email is sent, the signal

        ``registration.signals.user_registered`` will be sent, with

        the new ``User`` as the keyword argument ``user`` and the

        class of this backend as the sender.

        """

        username, email, password = cleaned_data['username'], cleaned_data['email'], cleaned_data['password1']

        if Site._meta.installed:

            site = Site.objects.get_current()

        else:

            site = RequestSite(request)

        new_user = RegistrationProfile.objects.create_inactive_user(username, email, password, site)

        signals.user_registered.send(sender=self.__class__,

                                     user=new_user,

                                     request=request)

        return new_user

______________________________________________
and from models.py:

______________________________________________

    def create_inactive_user(self, username, email, password,

                             site, send_email=True):

        """

        Create a new, inactive ``User``, generate a

        ``RegistrationProfile`` and email its activation key to the

        ``User``, returning the new ``User``.

        By default, an activation email will be sent to the new

        user. To disable this, pass ``send_email=False``.

        """

        new_user = User.objects.create_user(username, email, password)

        new_user.is_active = False

        new_user.save()

        registration_profile = self.create_profile(new_user)

        if send_email:

            registration_profile.send_activation_email(site)

        return new_user

    create_inactive_user = transaction.commit_on_success(create_inactive_user)

______________________________________________


Any thoughts would be much appreciated!
Matt

Kelvin Wong

unread,
May 30, 2014, 6:22:50 PM5/30/14
to django...@googlegroups.com
This is not an answer to your question, but I have used Django-registration before and ran into its limitations. Consider all the time you spent trying to debug this then consider that you'd probably already be done if you had just wrote a custom user and maybe salvaged some of the nicer code from Django-registration.

I've seen that error before. I seem to recall it comes from the way postgres handles transactions when one part of the transaction craps out. You might find some good info if you search for that specific message with the term postgres. Maybe also review the docs on Django transactions.

Matt Guy

unread,
Jun 2, 2014, 8:40:13 AM6/2/14
to django...@googlegroups.com
Thanks for your answer.

The prospect of dumping all of this and putting together a patchwork of my own code alongside registration is somewhat daunting at this stage. It also seems as though so many people use and recommend registration, including those successfully tackling this problem, that surely there must be a quick fix here!

I've sought postgres specific fixes to this problem, i've fiddled about in the sql console, i've tried a lot, but it's not seeming that simple. I think I just need a seasoned django warrior to wave a wand.

Any other thoughts?

Thanks,
Matt

James P

unread,
Jun 2, 2014, 12:43:19 PM6/2/14
to django...@googlegroups.com
I did my own extend and in the end I just created a one-to-one table for a user profile. When I extended Django-reg, I ended up overriding the user registration views for transactional processing of the additional table.
Reply all
Reply to author
Forward
0 new messages