Opened 10 years ago
Last modified 10 years ago
#23501 new Bug
remove/add fields programatically in modelform fails in admin
Reported by: | hadisunyoto | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | 1.7 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
model:
class Thickness(models.Model): value = models.DecimalField(primary_key=True, max_digits=7, decimal_places=2) is_active = models.BooleanField()
model form:
class ThicknessForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(ThicknessForm, self).__init__(*args, **kwargs) instance = getattr(self, 'instance', None) # edit if instance and instance.pk: del self.fields['value'] else: del self.fields['is_active'] class Meta: model = Thickness fields = '__all__'
admin:
class ThicknessAdmin(admin.ModelAdmin): list_display = ('value', 'is_active') form = ThicknessForm admin.site.register(Thickness, ThicknessAdmin)
refresh page, go to admin->Thickness, create one:
KeyError at /admin/thicknesses/thickness/add/
"Key 'is_active' not found in 'ThicknessForm'"
...
Error during template rendering
In template D:\env\lib\site-packages\django\contrib\admin\templates\admin\includes\fieldset.html, error at line 7
The highlighted line is number 7
6 {% for line in fieldset %}
7 <div class="form-row{% if line.fields|length_is:'1' and line.errors %} errors{% endif %}{% if not line.has_visible_field %} hidden{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}">
8 {% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %}
go to admin->Thickness again, modify one (created previously without using model form):
KeyError at /admin/thicknesses/thickness/0.55/
"Key 'value' not found in 'ThicknessForm'"
...
same error as above
Without admin, model form works as expected, it remove is_active when create, and it remove value when edit
Change History (6)
comment:1 by , 10 years ago
Description: | modified (diff) |
---|
comment:2 by , 10 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 10 years ago
I am aware of such methods, what i was trying to do is to push as much form control in modelform instead of in the admin. So next time when i have time i can build my own admin and reuse modelform without modifying the code again
comment:4 by , 10 years ago
You should be able to keep the del
logic, as long as you also use get_fields()
.
comment:5 by , 10 years ago
thank you for your quick response, in the mean time, i will try your suggestion
comment:6 by , 10 years ago
A little update:
i tried get_fields() method and still keep del intact, it turns out to be an error
KeyError at /admin/thicknesses/thickness/0.55/
'value'
21. def __init__(self, *args, **kwargs): 22. super(ThicknessForm, self).__init__(*args, **kwargs) 23. instance = getattr(self, 'instance', None) 24. 25. # edit 26. if instance and instance.pk: 27. del self.fields['value'] <-- 28. 29. class Meta:
occur in line 27
i guess i have to forget about the form and put everything in admin then. What worries me is there will be several models that requires the clean() method in form to check related fields, that means that i have two places (form and admin) that handles the form, and i don't think that's a good approach
I looked into this and I believe you can fix this by using ModelAdmin.get_fields() to exclude the field. It might be easiest to simply document that you should use that method and not the
del
approach.