3

I have a django auth user proxy model that has some extra permissions attached to it like so:

class User(User):
    class Meta:
        proxy = True
        permissions = (
            ("write_messages","May add new messages to front page"),
            ("view_maps","Can view the maps section"),
        )

Elsewhere in the model I have an object that has User as a foreign key:

class Project(models.Model):
    creation_date   = models.DateTimeField(auto_now_add=True)
    modify_date     = models.DateTimeField(auto_now=True)
    owner           = models.ForeignKey(User)

In one of my views I attempt to create a new project using the current user as the owner

@login_required
def new_project(request):
    project = Project.objects.create(owner=request.user)

This, however, returns the error:

Cannot assign "<User: mwetter>": "Project.owner" must be a "User" instance.

I'm assuming that the foreign key owner in the project object is referring to the base class for Django User instead of my proxy class. Is there a way to refer to my proxy user as a foreign key instead?

Mark Wetter
  • 68
  • 1
  • 6
  • Possible duplicate http://stackoverflow.com/questions/3006753/how-to-convert-request-user-into-a-proxy-auth-user-class – San4ez May 08 '12 at 18:47

3 Answers3

22

In addition to what @DavidRobinson said, you need to be careful about creating foreign keys to proxy models. A proxy model is still a subclass of the model it proxies, despite being for all intents and purposes the same as the model. If you have a foreign key to the proxy it will not accept the base class, however a foreign key to the base class will accept the the proxy. Take the following for example.

Given:

class UserProxy(User):
    class Meta:
        proxy = True
    ...

class User(models.Model):
    ...

The following will raise an exception:

class SomeModel(models.Model):
    user = models.ForeignKey(UserProxy)

user = User.objects.get(username='some_user')
instance = SomeModel.objects.create(user=user)

But, the following will work fine:

class SomeModel(models.Model):
    user = models.ForeignKey(User)

user = UserProxy.objects.get(username='some_user')
instance = SomeModel.objects.create(user=user)

This is due to the directionality of the relationship. UserProxy is-a User, but User is not a UserProxy.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
1

Why are you calling your proxy class User, which is guaranteed to lead to confusion between that and django.contrib.auth.models.User? Why not UserProxy, or MyUser? Then it could be distinguished whenever you use it.

David Robinson
  • 77,383
  • 16
  • 167
  • 187
  • Hmmm, that's a good point actually. Up until now I haven't used `User` in any context other than the built-in functions like `user.has_perm()`. I can't remember my original reasoning behind using the same name, so I'll try changing it to see what breaks. – Mark Wetter May 08 '12 at 18:55
  • I'm going to accept this as the best answer since its the obvious step that I should have taken. At this point I'm delving into the jungle of extended user models and all of the joy that it entails. – Mark Wetter May 08 '12 at 20:36
0

Try to assign id instead of object

project = Project.objects.create(owner_id=request.user.pk)
San4ez
  • 8,091
  • 4
  • 41
  • 62