Code

Opened 7 years ago

Closed 7 years ago

Last modified 5 years ago

#6032 closed (duplicate)

Make User and Group extendable

Reported by: Benjamin Wiegand <beewee@…> Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords: database, user, group, extension
Cc: webteam@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Hi,

I'm developing a django application where I've additional data to store for users (e.g. a signature, settings, etc.). I solved this by creating a new model called UserProfile, which stores this data and has a ForeignKey user to the django User object. This sollution works fine for some small things but sometimes it's really copious, e.g. if I want to get the user data of all users that belong to a special group. In this case I had to do something like this:

group = Group.objects.get(id=123)
users = group.user_set.all()
profiles = UserProfile.objects.filter(user__id__in=[u.id for u in users])

Now I'm wondering whether extending the User and Group model like this would be possible:

# in models.py
from django.contrib.auth.models import User, Group

class MyUser(User):
    signature = forms.CharField()
    post_count = forms.IntegerField()


class MyGroup(Group):
    def get_absolute_url():
        return 'my_own_url'
# in settings.py
DJANGO_USER_MODEL = 'models.MyUser'
DJANGO_GROUP_MODEL = 'models.MyGroup'

signature and post_count then would be stored in the same database table as the normal user data (username, date_joined, etc.).

Attachments (0)

Change History (7)

comment:1 Changed 7 years ago by Max Derkachev <mderk@…>

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

It is possible, but with minor hack - You should reassign default manager. E.g.:

from django.contrib.auth.models import User, UserManager
manager = UserManager()
class MyUser(User):
    signature = forms.CharField()
    post_count = forms.IntegerField()
    objects = manager
    _default_manager = manager    

Otherwise, the inherited manager won't see the new fields in the subclass.

comment:2 Changed 7 years ago by Benjamin Wiegand <beewee@…>

hm, sorry, but this is not really what I want, I think.
This creates a new model and database table for MyUser instead of altering the auth_user table.
What I want is that django handles internally with the extended user object too.

comment:3 Changed 7 years ago by Max Derkachev <mderk@…>

You can define the same table in class Meta.

comment:4 Changed 7 years ago by Benjamin Wiegand <beewee@…>

This doesn't work too :/
If I set the table name to "auth_user" in the Meta class, nothing happens when deleting the database and executing syncdb again: The auth_user table still doesn't contain a signature field and the User objects returned by group.user_set don't have a signature attribute too :/

comment:5 Changed 7 years ago by Benjamin Wiegand <beewee@…>

  • Cc webteam@… added

comment:6 Changed 7 years ago by Benjamin Wiegand <beewee@…>

  • Cc webteam@… added; webteam@… removed

comment:7 Changed 7 years ago by ubernostrum

  • Resolution set to duplicate
  • Status changed from new to closed

The request here is essentially for model subclassing to work, which makes this a duplicate of #1656.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.