#8241 closed (fixed)
Primary ForeignKeys don't work with FormSets
Reported by: | Samuel Cormier-Iijima | Owned by: | Brian Rosner |
---|---|---|---|
Component: | contrib.admin | Version: | dev |
Severity: | Keywords: | ||
Cc: | sciyoshi@…, ville@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Using this UserProfile as an example:
class UserProfile(models.Model): user = models.OneToOneField(primary_key=True) nickname = models.CharField(max_length=30) from django.contrib.auth.models import User from django.contrib.auth.admin import UserAdmin from django.contrib.admin import site, StackedInline class UserProfileAdmin(StackedInline) model = UserProfile max_num = 1 UserAdmin.inlines = UserAdmin.inlines + [UserProfileAdmin] site.unregister(User) site.register(User, UserAdmin)
Trying to save a User from the admin causes a KeyError: 'user_id' because the primary key doesn't get rendered in the form.
Attachments (3)
Change History (19)
comment:1 by , 16 years ago
comment:2 by , 16 years ago
Component: | Uncategorized → Admin interface |
---|---|
milestone: | → 1.0 |
Triage Stage: | Unreviewed → Accepted |
comment:4 by , 16 years ago
Replying to mremolt:
Isn't this a duplicate for or at least related to #7947 ?
I don't think so; applying the patch from that ticket doesn't fix the bug, and the same behavior also occurs if we have
user = models.ForeignKey(User, primary_key=True)
I think the problem could be fixed somewhere around add_fields in BaseModelFormSet:
def add_fields(self, form, index): """Add a hidden field for the object's primary key.""" if self.model._meta.has_auto_field: self._pk_field_name = self.model._meta.pk.attname form.fields[self._pk_field_name] = IntegerField(required=False, widget=HiddenInput) super(BaseModelFormSet, self).add_fields(form, index)
If the primary key isn't an AutoField it doesn't get added to the fields here...
comment:5 by , 16 years ago
The following patch fixes it for me (for OneToOneFields the patch from #7949 needs to be applied first), but probably breaks other things; namely, model_formsets fails. If anybody has ideas on how to better implement this let me know...
by , 16 years ago
Attachment: | 8241.patch added |
---|
comment:6 by , 16 years ago
Has patch: | set |
---|---|
Needs tests: | set |
Patch needs improvement: | set |
comment:7 by , 16 years ago
Patch needs improvement: | unset |
---|
sciyoshi, first of all, thanks for your patch. It inspired me for further analysis of the problem. :)
From what I've discovered, your patch suffers from the following:
- It curcumvents into the naming convention of form fields and adds a form field named user_id (i.e., taken as field.attname, not as field.name). At first glance, that seems to be ok: the field is filled by model_to_dict(), passed thru browser POST, but then ignored by save_instance(). Alas, that would break things if a model had TWO fields like user=OneToOneField() and user_id=CharField(). We shouldn't be messing with the naming convention: all form fields should always use field.name as their names.
- The patch breaks BaseModelFormSet.add_fields() contract, which currently adds a new field if (and only if) a primary key is an AutoField -- what I consider to be a desired behaviour.
I'm attaching the updated patch (vs [8461]), which resolves the both problems.
by , 16 years ago
Attachment: | onetoone_admin.8461.diff added |
---|
comment:8 by , 16 years ago
Also, I didn't get the idea behind parent_link, which was in your patch, and also was discussed in #7947. I replaced that with:
if not kwargs.get('primary_key', False): kwargs['editable'] = False
which I admit might be wrong for some obscure reason...
comment:9 by , 16 years ago
by , 16 years ago
Attachment: | onetoone_admin.8541.diff added |
---|
comment:10 by , 16 years ago
Note: I really don't like my drill down until we find a "real" pk approach; but I don't have enough deep knowledge of django/db internals, so that was the only way that seemed correct to me (more or less).
comment:11 by , 16 years ago
Cc: | added |
---|
comment:12 by , 16 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
It appears this ticket has been caught in the middle of some commit rapid fire. In the fire the issue reported here is fixed. The issue that semenov brings up is not related, but I think should be fixed. Can you please open a ticket talking about the namespace stomping. Please reopen if the issue reported has not been fixed on trunk with detailed and concise use cases.
comment:13 by , 16 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
Ok. I take back that this is fixed. I had a bad test case. Reopening.
comment:14 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | reopened → new |
That should be