Opened 15 years ago

Closed 15 years ago

Last modified 12 years ago

#10953 closed (fixed)

Proxy model of a proxy model is of incorrect type.

Reported by: Tai Lee Owned by: Jacob
Component: Database layer (models, ORM) Version: dev
Severity: Keywords: proxy type foreign key
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

If you proxy a model that is already a proxy, it will be of the same type as the first proxy. If the second proxy is used in a foreign key, you will not be able to create any model objects which have a value for that foreign key because they will fail the type check validation.

This means we can only ever proxy actual models, and cannot create a base proxy model to subclass as necessary.

# models.

from django.contrib.auth import models as auth_models
from django.db import models

class User1(auth_models.User):
	class Meta:
		proxy = True

class User2(User1):
	class Meta:
		proxy = True

class Something(models.Model):
	user = models.ForeignKey(User2)

# interactive shell.

>>> from myapp.models import User1, User2, Something

>>> type(User1.objects.get(username='admin'))
<class 'myapp.models.User1'>

>>> type(User2.objects.get(username='admin'))
<class 'myapp.models.User1'>

>>> Something.objects.create(user=User2.objects.get(username='admin'))
Traceback (most recent call last):
  File "<console>", line 1, in ?
  File "/path/to/django/db/models/manager.py", line 126, in create
    return self.get_query_set().create(**kwargs)
  File "/path/to/django/db/models/query.py", line 283, in create
    obj = self.model(**kwargs)
  File "/path/to/django/db/models/base.py", line 308, in __init__
    setattr(self, field.name, rel_obj)
  File "/path/to/django/db/models/fields/related.py", line 270, in __set__
    raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' %
ValueError: Cannot assign "<User1: admin>": "Something.user" must be a "User2" instance.

Attachments (2)

proxy-proxy.diff (1.8 KB ) - added by Alex Gaynor 15 years ago.
proxy-proxy.2.diff (3.2 KB ) - added by Alex Gaynor 15 years ago.

Download all attachments as: .zip

Change History (8)

comment:1 by Tai Lee, 15 years ago

Looks like the incorrect model is being assigned to the manager (or simply being copied unchanged from the base proxy class). This causes any querysets from the manager to create model objects of the wrong type.

>>> User1.objects.model
<class 'myapp.models.User1'>
>>> User2.objects.model
<class 'myapp.models.User1'>

by Alex Gaynor, 15 years ago

Attachment: proxy-proxy.diff added

comment:2 by Alex Gaynor, 15 years ago

Has patch: set
milestone: 1.1
Triage Stage: UnreviewedAccepted

by Alex Gaynor, 15 years ago

Attachment: proxy-proxy.2.diff added

comment:3 by Armin Ronacher, 15 years ago

Owner: changed from nobody to Armin Ronacher

The fix for this ticket, including the one for #10955 which is related is attached to my github repo: http://github.com/mitsuhiko/django/tree/ticket-10953

comment:4 by Jacob, 15 years ago

Owner: changed from Armin Ronacher to Jacob
Status: newassigned

comment:5 by Jacob, 15 years ago

Resolution: fixed
Status: assignedclosed

(In [10738]) Fixed #10953, #10955: proxies of proxies now work correctly, though I still don't quite understand why you'd want to do such a thing. Thanks, Armin Ronacher.

comment:6 by Jacob, 12 years ago

milestone: 1.1

Milestone 1.1 deleted

Note: See TracTickets for help on using tickets.
Back to Top