Opened 14 years ago
Closed 12 years ago
#14802 closed New feature (wontfix)
feature request: add a method to Fields that is used to render the field as read-only
Reported by: | nickname123 | Owned by: | Greg Turner |
---|---|---|---|
Component: | contrib.admin | Version: | 1.2 |
Severity: | Normal | Keywords: | sprintdec2010 hidden_widget |
Cc: | Triage Stage: | Design decision needed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | yes |
Description
It is possible to override the default widget that is used to render a custom model field... however the hidden_widget is more difficult. The only way appears to be on a per model basis by changing the widget in the model admin. This can be very difficult/impractical when inheriting models that make use of the custom field with the field set to readonly in the model admin.
For example, a simple field that uses a custom widget:
class CustomFileWidget(forms.FileInput): return mark_safe(u"CustomFileWidget was used: %s" % super(CustomFileWidget, self).render(name, value, attrs)) class CustomFileFormField(forms.FileField): def __init__(self, *args, **kwargs): kwargs['widget'] = CustomFileWidget super(CustomFileFormField, self).__init__(*args, **kwargs) class CustomFileField(models.FileField): def formfield(self, **kwargs): return super(CustomFileField, self).formfield(form_class=CustomFileFormField,**kwargs)
However, there does not appear to be a kwarg for hidden_widget and using something like the following will not work:
class CustomFileFormField(forms.FileField): hidden_widget = CustomFileWidget widget = CustomFileWidget class CustomFileField(models.FileField): def formfield(self, **kwargs): return super(CustomFileField, self).formfield(form_class=CustomFileFormField,**kwargs)
Change History (15)
follow-up: 2 comment:1 by , 14 years ago
Keywords: | sprintdec2010 added |
---|---|
Resolution: | → wontfix |
Status: | new → closed |
Triage Stage: | Unreviewed → Design decision needed |
follow-up: 3 comment:2 by , 14 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
Replying to cogat:
The admin app doesn't render hidden_widget at all, it just displays readonly fields (using
getattr(modelinstance, fieldname)
). AFAICS hidden_widget is only used by form previews and form wizards for holding on to copies of fields that were entered in an earlier view.
If you are asking for a customised way to render a read-only field, then it might be helpful to know that you can pass a callable to readonly_fields that renders the result you want.
class Song(models.Model): band = models.ForeignKey(Band) title = CustomModelField(max_length=100) def rendertitle(self): return "A custom rendering of %s" % self.title class SongAdmin(admin.ModelAdmin): exclude = ('title',) readonly_fields = ('rendertitle', )
Wouldn't it be a better idea (in the future) to use a widget to render the readonly value so that the default appearance can be overridden? Using a field like that may be nice in some situations, but it doesn't work well for my use case.
I don't think it would work well with any abstract model that is used repeatedly because you have to remember to add the callable to readonly_fields in every model's admin entry that inherits it. And also for admin inlines.
follow-up: 7 comment:3 by , 14 years ago
milestone: | 1.3 |
---|
Just to clarify, a widget in Django is its representation of an HTML input element, so it doesn't make sense to use it for anything that doesn't involve displaying and handling an input element. So for read-only fields there's no need to use a widget.
Given this, I think you're asking for each Field to have a method that is called by admin that renders the field as a read-only HTML. That's something I could get behind (it's better to attach field display to fields than to models, and there are currently silly special-cases for rendering BooleanFields as icons in the current code) but it needs a design decision. Particularly, would the same method, or a variation on it, be used to render the field in admin list views? What about mechanisms for requiring external javascript/css files needed by the rendering? What about specifying read-only fields (so the same method can be used) in non-admin forms?
However, without a patch this won't make it into 1.3, so I'll remove the milestone.
comment:4 by , 14 years ago
Summary: | feature request: ability to override default hidden_widget used to render a custom model field when marked as readonly in the admin → feature request: add a method to Fields that is used when rendering as readonly |
---|
comment:5 by , 14 years ago
Summary: | feature request: add a method to Fields that is used when rendering as readonly → feature request: add a method to Fields that is used to render the field as read-only |
---|
follow-up: 8 comment:6 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | reopened → new |
I'll have a crack at this.
comment:7 by , 14 years ago
Replying to cogat:
Just to clarify, a widget in Django is its representation of an HTML input element, so it doesn't make sense to use it for anything that doesn't involve displaying and handling an input element. So for read-only fields there's no need to use a widget.
Given this, I think you're asking for each Field to have a method that is called by admin that renders the field as a read-only HTML. That's something I could get behind (it's better to attach field display to fields than to models, and there are currently silly special-cases for rendering BooleanFields as icons in the current code) but it needs a design decision. Particularly, would the same method, or a variation on it, be used to render the field in admin list views? What about mechanisms for requiring external javascript/css files needed by the rendering? What about specifying read-only fields (so the same method can be used) in non-admin forms?
However, without a patch this won't make it into 1.3, so I'll remove the milestone.
In regards to your comment about widgets being the wrong term... the html input tag does have a readonly attribute (http://www.w3schools.com/tags/att_input_readonly.asp). I was talking about using this since widgets are the current way of displaying form fields that are not readonly. This seemed to be the "correct" way to do it.
However, I did not put much thought into how it would be best achieved because I was not sure if the feature had been left out of Django on purpose.
A "to html" method might be a better idea, but I am still in favor using a widget. I think a widget gives a little more abstraction and fits better with the current design. Using a widget opposed to a method on the model would have the benefit of being easily overridden too. I think it is a nifty feature to be able to override the default widgets on the model forms used by the admin interface and there is no reason not to allow the same level of tweaking with readonly fields. (http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides and http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-default-field-types-or-widgets)
comment:9 by , 14 years ago
A "to readonly html string" method on the field is a better idea. I misread your suggestion somewhat earlier. Like I said above, I hadn't put too much thought into the idea because I wasn't sure how other people would react to the feature request. Glad you gave some input =).
comment:10 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → New feature |
comment:11 by , 14 years ago
UI/UX: | set |
---|
comment:15 by , 12 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
I don't really like the idea of using a widget to render readonly fields, it just seems like overkill.
The admin app doesn't render hidden_widget at all, it just displays readonly fields (using
getattr(modelinstance, fieldname)
). AFAICS hidden_widget is only used by form previews and form wizards for holding on to copies of fields that were entered in an earlier view.If you are asking for a customised way to render a read-only field, then it might be helpful to know that you can pass a callable to readonly_fields that renders the result you want.