#8097 closed Uncategorized (worksforme)
Many-to-many self-referential intermediates in admin: <Friendship> has more than 1 ForeignKey to <Person>
Reported by: | Boo | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | dev |
Severity: | Normal | Keywords: | ManyToManyField, admin |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
This URL http://127.0.0.1:8000/admin/foo/person/add/ returns traceback:
Environment: Request Method: GET Request URL: http://127.0.0.1:8000/admin/foo/person/add/ Django Version: 1.0-alpha-SVN-8199 Python Version: 2.5.2 Installed Applications: ['django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'testcase.foo'] Installed Middleware: ('django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.doc.XViewMiddleware') Traceback: File "/opt/local/lib/python2.5/site-packages/django/core/handlers/base.py" in get_response 87. response = callback(request, *callback_args, **callback_kwargs) File "/opt/local/lib/python2.5/site-packages/django/contrib/admin/sites.py" in root 156. return self.model_page(request, *url.split('/', 2)) File "/opt/local/lib/python2.5/site-packages/django/views/decorators/cache.py" in _wrapped_view_func 44. response = view_func(request, *args, **kwargs) File "/opt/local/lib/python2.5/site-packages/django/contrib/admin/sites.py" in model_page 173. return admin_obj(request, rest_of_url) File "/opt/local/lib/python2.5/site-packages/django/contrib/admin/options.py" in __call__ 259. return self.add_view(request) File "/opt/local/lib/python2.5/site-packages/django/contrib/admin/options.py" in add_view 504. for FormSet in self.get_formsets(request): File "/opt/local/lib/python2.5/site-packages/django/contrib/admin/options.py" in get_formsets 340. yield inline.get_formset(request, obj) File "/opt/local/lib/python2.5/site-packages/django/contrib/admin/options.py" in get_formset 743. extra=self.extra, max_num=self.max_num) File "/opt/local/lib/python2.5/site-packages/django/forms/models.py" in inlineformset_factory 479. fk = _get_foreign_key(parent_model, model, fk_name=fk_name) File "/opt/local/lib/python2.5/site-packages/django/forms/models.py" in _get_foreign_key 464. raise Exception("%s has more than 1 ForeignKey to %s" % (model, parent_model)) Exception Type: Exception at /admin/foo/person/add/ Exception Value: <class 'testcase.foo.models.Friendship'> has more than 1 ForeignKey to <class 'testcase.foo.models.Person'>
Please, see the testcase to reproduce this bug.
Attachments (1)
Change History (4)
by , 16 years ago
Attachment: | testcase.tar.gz added |
---|
follow-up: 2 comment:1 by , 16 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
There is no problem actually, you only need to define the fkey that admin app should use for the relation. If you have model like this (your testcase):
class Person(models.Model):
name = models.CharField(max_length=20)
friends = models.ManyToManyField('self', through='Friendship', related_name='friend_of', symmetrical=False)
def unicode(self):
return self.name
class Friendship(models.Model):
first = models.ForeignKey(Person, related_name='rel_from_set')
second = models.ForeignKey(Person, related_name='rel_to_set')
date_friended = models.DateTimeField(auto_now_add=True)
def unicode(self):
- return u'%s
- %s' % (self.first.name, self.second.name)
You need to specify fk_name attr on inline object:
class FriendshipInline(admin.TabularInline):
model = Friendship
fk_name = 'first'
Similarly could could edit the second side of the relation like this on a single page:
class SecondFriendshipInline(admin.TabularInline):
model = Friendship
fk_name = 'second'
Your PersonAdmin would be then like this:
class PersonAdmin(admin.ModelAdmin):
inlines = [FriendshipInline, SecondFriendshipInline]
admin.site.register(Person, PersonAdmin)
This subtle config addon is however not mentioned currently in the docs, you need to go to the source.
comment:2 by , 16 years ago
Hmm.. Actually, this is already documented here:
I guess this was not there 5 hours ago..
--
Milos
comment:3 by , 12 years ago
Easy pickings: | unset |
---|---|
Severity: | → Normal |
Type: | → Uncategorized |
UI/UX: | unset |
The documentation seems to have been moved from underneath Milos' link. Here's an updated link:
TestCase to repeat the problem