views:

305

answers:

4

Hey,

I am writing simple site that requires users and profiles to be handled. The first initial thought is to use django's build in user handling, but then the user model is too narrow and does not contain fields that I need. The documentation mentions user profiles, but user profiles section has been removed from djangobook covering django 1.0 (ideally, the solution should work with django 1.2), and the Internet is full of different solutions, not making the choice easier (like user model inheritance, user profiles and django signals, and so on).

I would like to know, how to write this in good, modern, fast and secure way. Should I try to extend django builtin user model, or maybe should I create my own user model wide enough to keep all the information I need? Below you may find some specifications and expectations from the working solution:

  • users should be able to register and authenticate
  • every user should have profile (or model with all required fields)
  • users dont need django builtin admin panel, but they need to edit their profiles/models via simple web form

Please, let me know how do you solve those issues in your applications, and what is the best current way to handle users with django. Any links to articles/blogs or code examples are highly appreciated!

A: 

Django supports a UserProfile model (of your own creation) right out of the box. You can assign this in your settings.py file with: AUTH_PROFILE_MODULE. That being said, I will agree with you that it is a little confusing at first.

How I handled it was to create my own UserProfile model with the fields I wanted and hook it into the Django User model via the settings (above). I believe this is the preferred way and probably better than extending the base User model.

You can access your profile through User.get_profile().

There are a couple projects on github that are UserProfile oriented. If you wanted some code examples, you could look there.

thornomad
+2  A: 

Seems to me like the current version of the Django docs and the Django book both have sections for this.

Daniel DiPaolo
+3  A: 

users should be able to register and authenticate

django.contrib.auth is the module you want. Be sure to check the docs for custom login forms.

every user should have profile (or model with all required fields)

You need to set settings.AUTH_PROFILE_MODULE, as noted by others.

Information about setting up the user profile model is available for the latest version, 1.1, and 1.0. It hasn't been dropped.

users dont need django builtin admin panel, but they need to edit their profiles/models via simple web form

You can create a form and view just like you would for any other app; maybe make a "user control panel" app for handling these things. Your views would then interact with the django.contrib.auth.models.User and django.contrib.auth.models.Group models. You can set this up to do whatever you need.

EDIT: Responding to your questions-in-the-form-of-an-answer (paging Alex Trebek)...

The second version of djangobook, covering django 1.0 (that is way closer to 1.2 than 0.96) no longer has that information anywhere, what makes me highly confused - has anything changed? Is there other, better, more secure way to handle users and their profiles? Therefore this question asked.

I wouldn't recommend djangobook as a reference; it's out of date on this topic. User profiles exist and I'm using them in my Django 1.1.1 site; I'm even populating them from NIS.

Please use the links I provided above. They go directly to the actual Django documentation and are authoritative.

By the way, I forgot to ask, if the way you all refer to (that is AUTH_PROFILE_MODULE) will create automatically upon registration

Answered in the docs.

and require the profile to exist upon any action (user withoud existing, filled profile should not exists, this is why I was thinking about extending User model somehow)?

The profile needs to exist if User.get_profile() is called.

Will it get updated as well (people are mentioning 'signals' on various blogs related to this subject)?

It's like any other model: it only gets updated when you change the fields and call save().

The signal part is how you hook in a function to create a profile for a new User:

from django.db.models.signals import post_save
from django.contrib.auth import User
from myUserProfileApp import UserProfile

def make_user_profile(sender, **kwargs):
    if 'created' not in kwargs or not kwargs['created']:
        return

    # Assumes that the `ForeignKey(User)` field in "UserProfile" is named "user".
    profile = UserProfile(user=kwargs["instance"])
    # Set anything else you need to in the profile, then...
    profile.save()

post_save.connect(make_user_profile, sender=User, weak=False)

This only creates a new profile for a new User. Existing Users need to have profiles manually added:

$ ./manage.py shell
>>> from django.contrib.auth import User
>>> from myUserProfileApp import UserProfile
>>> for u in User.objects.all():
...  UserProfile(user=u).save() # Add other params as needed.
...

If you have some users with profiles and some without, you'll need to do a bit more work:

>>> for u in User.objects.all():
...  try:
...   UserProfile(user=u).save() # Add other params as needed.
...  except:
...   pass
Mike DeSimone
A: 

Thank you all for your answers! I know that django dev documentation mentions user profiles, but does it very briefly (roughly few lines) and links to djangobook containing information about user profiles, but... to its first version, covering django 0.96. The second version of djangobook, covering django 1.0 (that is way closer to 1.2 than 0.96) no longer has that information anywhere, what makes me highly confused - has anything changed? Is there other, better, more secure way to handle users and their profiles? Therefore this question asked.

SpankMe
By the way, I forgot to ask, if the way you all refer to (that is AUTH_PROFILE_MODULE) will create automatically upon registration, and require the profile to exist upon any action (user withoud existing, filled profile should not exists, this is why I was thinking about extending User model somehow)? Will it get updated as well (people are mentioning 'signals' on various blogs related to this subject)?
SpankMe
When you do this, and don't leave a comment on our answers, it doesn't tell any of us that you responded...
Mike DeSimone