﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
18005	Add support for ManyToManyFields on proxy models	Bradley Ayers <bradley.ayers@…>	nobody	"It appears Django already supports this, but explicitly checks for and prevents it from working:

https://code.djangoproject.com/browser/django/trunk/django/db/models/base.py#L123
{{{
if (new_class._meta.local_fields:
        or new_class._meta.local_many_to_many):
    raise FieldError(""Proxy model '%s' contains model fields."" % name)
}}}

By simply removing the second half of the condition, ``ManyToManyField``s work on
proxy models.

In my current project I'm proxying the ``auth.User`` as ``users.User``, and I want to add a M2M
relationship to ``core.District``. I don't want to modify core, so I'd like to
add the relationship to the ``users.User`` proxy model:

{{{
from django.contrib.auth.models import User as AuthUser

class User(AuthUser):
    districts = models.ManyToManyField(""core.District"")

    class Meta:
        proxy = True
}}}

Running ``./manage.py sql users`` shows that the correct SQL is generated:

{{{
BEGIN;
CREATE TABLE ""users_user_districts"" (
    ""id"" integer NOT NULL PRIMARY KEY,
    ""user_id"" integer NOT NULL,
    ""district_id"" integer NOT NULL REFERENCES ""core_district"" (""id""),
    UNIQUE (""user_id"", ""district_id"")
)
;
COMMIT;
}}}

I wrote a crude test case, and it all seems to work:

{{{
user = User.objects.create_user(""username"", ""fake@example.com"", ""password"")
district = District.objects.create(name=""Foo"")
user.districts.add(district)

user = User.objects.get(pk=user.pk)  # use fresh version
assert district.users.count() == 1
assert district.users.all()[0].pk == user.pk

user.districts.clear()
user = User.objects.get(pk=user.pk)  # use fresh version
assert user.districts.count() == 0
assert list(user.districts.all()) == []
}}}

The Django test suite passes using SQLite:

{{{
$ ./runtests.py --settings=test_sqlite
Creating test database for alias 'default'...
Creating test database for alias 'other'...
...<snip>....
----------------------------------------------------------------------
Ran 4657 tests in 1007.250s

OK (skipped=115, expected failures=2)
Destroying test database for alias 'default'...
Destroying test database for alias 'other'...
}}}

Are there any arguments against this?
"	New feature	closed	Database layer (models, ORM)	1.4	Normal	wontfix			Unreviewed	0	0	0	0	0	0
