Creating users represented by two models in OneToOne relation

15 views
Skip to first unread message

quenti...@gmail.com

unread,
Apr 26, 2018, 11:55:40 PM4/26/18
to Django users

Hi,


This quesion is related to the common pattern of representing a site

user (henceforth referred to as "member"), by two models that have a

one-to-one relation:


1. A builtin `contrib.auth.models.User' model, used for authentication,

   that holds credentials and basic information.


2. An application specific `Profile' model with additional personal

   information, such as language for example. `Profile.user' is a

   `OneToOneField' pointing to `auth.User'


My questions relate to the creation of such members, for which the

responsible view must populate and save two model instances with the

submitted form data.


• What approaches would you recommend to implement the member creation

  form?

• How could generic class-based views be efficiently leveraged to handle

  member creation?


I briefly present my current solution below, with its limitations.


1. Form: a `ModelForm' associated to the `User' model, with extra fields

   corresponding to the profile information.


class MemberForm(ModelForm):
   
# These fields map to those on the Profile model
   
# One for brevity here, but think of many more in practice
    language
= forms.CharField(
        max_length
=3,
        widget
=forms.Select(choices=Profile.LANGUAGES)
   
)


   
class Meta:
        model
= User
        fields
= ['first_name', 'last_name', 'email']


1. View: a `CreateView' subclass associated to the `User' model,

   overriding the `form_valid()' method in which the `Profile' model is

   populated by hand from the form's `cleaned_data' extra fields.


class MemberCreate(CreateView):
    form_class
= PanelMemberForm

   
def form_valid(self, form):
        language
= form.cleaned_data['language']
       
with transaction.atomic():
            user
= form.save()
           
Profile(user=user, language=language).save()
       
return HttpResponseRedirect(self.get_success_url())



The obvious limitation I see to this approach is that when fields are

added or modified on the `Profile' model, both the form and the view

must be carfully updated. I suspect this will not be very easily

maintained code when the `Profile' model grows…


Thanks in advance for any insights you might share (and for having read

thus far)


Quentin







Reply all
Reply to author
Forward
0 new messages