On Oct 30, 3:53 am, Alessandro Ronchi <alessandro.ron...@soasi.com>
wrote:
> I've made a Profile model (Socio) for my users and now I need to be able to
> edit the users detail in profile model in admin.
>
> THe problem is that I can add an Inline only from User to Profile, because
> User doesn't have a foreign key to profile.

I had a similar problem. I have a Person class, which is effectively a
Profile (but may exist without an attached User). It is trivial to
have the Person fields appear in the User admin page, but not the
other way around.

My solution was to have a custom PersonAdminForm, which allows for
setting of the username and password (and validates these, creating a
new user if one was not previously attached).  This form is then
attached to the PersonAdmin class.

Hope the snippets below help.

person/admin.py

class PersonAdmin(VersionAdmin):
    model = Person
    form = PersonAdminForm

person/forms.py

class PersonAdminForm(forms.ModelForm):
    user_active = forms.BooleanField(required=False, label='Can log
in',
        help_text="Allow this person to log in to the web interface.")
    username = forms.CharField(required=False)
    password1 = forms.CharField(required=False,
        label='Password',
        widget=forms.PasswordInput)
    password2 = forms.CharField(required=False,
        label='Password (repeat)',
        widget=forms.PasswordInput)

    groups = forms.ModelMultipleChoiceField(required=False,
        queryset=auth.models.Group.objects)

    def __init__(self, *args, **kwargs):
        forms.ModelForm.__init__(self, *args, **kwargs)
        person = kwargs.get('instance', None)
        if person:
            user = person.user
            if user:
                self.fields['groups'].queryset = person.company.groups
                self.fields['groups'].initial = map(lambda x:x.pk,
                    user.groups.all())
                self.fields['user_active'].initial = user.is_active
                self.fields['username'].initial = user.username
                self.fields['password2'].help_text = 'Enter the same
password into both boxes to change it.'
                self.fields['user_active'].help_text = 'Allow %s to
log in to the web interface.' % user.name
                self.fields['active'].help_text = 'Allow %s to be
rostered on for shifts.' % user.name

            else:
                self.fields['groups'].widget = forms.HiddenInput()
                self.fields['groups'].help_text = 'People must be able
to log in to assign them to groups.'
            self.fields['company'].widget = forms.HiddenInput()
            self.fields['company'].help_text = 'People cannot be moved
between companies.'
        else:
            self.fields['groups'].widget = forms.HiddenInput()
            self.fields['groups'].help_text = "Choose groups after
creating the person."
            # TODO: use Ajax to load the group list after the company
has been chosen.

    class Meta:
        model = Person

    def clean_username(self):
        """
        See if there is already a user with this username.  If this
username
        is already associated with the user that is attached to this
person,
        then that is okay.
        """
        username = self.cleaned_data['username']
        if username == "" and (self.cleaned_data['user_active'] or
self.instance.user):
            raise forms.ValidationError(_("A username must be supplied
to enable login."))
        users = auth.models.User.objects.filter(username=username)
        if self.instance.user:
            users = users.exclude(pk=self.instance.user.pk)
        if users.count() != 0:
            raise forms.ValidationError(_("A user with that username
already exists."))

        return username

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1", "")
        password2 = self.cleaned_data["password2"]
        if password1 != password2:
            raise forms.ValidationError(_("The two password fields
didn't match."))
        return password2

    def clean_groups(self):
        co_groups = self.cleaned_data['company'].groups.all()
        return [group for group in self.cleaned_data['groups'] \
                    if group in co_groups]

    def save(self, commit=True):
        """
        If there isn't a user linked to this person, and there is a
username,
        then we need to create a user.  Otherwise, we need to alter
the
        values in the existing user object.

        """
        forms.ModelForm.save(self, commit=False)

        if self.cleaned_data['username'] != "":
            if self.instance.user:
                user = self.instance.user
                # Set groups: easiest method-clear then re-add.
                user.groups.clear()
                user.groups.add(*self.cleaned_data['groups'])
            else:
                user = auth.models.User()


            user.username = self.cleaned_data['username']
            if self.cleaned_data['password2'] != "":
                user.set_password(self.cleaned_data['password2'])
            user.active = self.cleaned_data['user_active']

            user.save()

            if not self.instance.user:
                self.instance.user = user
                # Add this person to the default group
                if not self.cleaned_data['groups']:
                    user.groups.add
(self.instance.company.default_group)
                else:
                    user.groups.add(*self.cleaned_data['groups'])

        # Must return the result of the super.save()
        return forms.ModelForm.save(self, commit)

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to