Created
July 4, 2017 14:28
-
-
Save shadiakiki1986/e27edd06f2cb3ad4110405235849ebfb to your computer and use it in GitHub Desktop.
Django simplest read-only widget
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Based on the below answer on the SO question: | |
# In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited? | |
# https://stackoverflow.com/a/15134622/4126114 | |
# | |
# Usage of either widget classes below: | |
# class MyForm(forms.ModelForm): | |
# class Meta: | |
# widgets = { | |
# 'field': ReadOnlyWidgetSimple(), | |
# 'foreign_key': ReadOnlyWidgetMyModel() | |
# } | |
from django.forms import widgets | |
# For non-foreign-key fields, display them in <p>...</p> | |
# Note the "str(...)" necessary for things like datetime objects | |
# Also, without the <p>...</p>, the field in bootstrap_form does not show up aligned properly | |
class ReadOnlyWidgetSimple(widgets.Widget): | |
"""Some of these values are read only - just a bit of text...""" | |
def render(self, _, value, attrs=None): | |
return "<p>"+str(value)+"</p>" | |
# For foreign-key fields, display their __str()__ result | |
# Usage: Define a class inheriting from this, and which defines the "model" attribute | |
# e.g. | |
# class ReadOnlyWidgetMyModel(ReadOnlyWidgetModel): | |
# model = MyModel # <<<<< put your model class here | |
class ReadOnlyWidgetModel(widgets.Widget): | |
model = None | |
"""Some of these values are read only - just a bit of text...""" | |
def render(self, _, value, attrs=None): | |
if not self.model: raise Exception("Define model") | |
v2 = self.model.objects.get(id=value) | |
v2 = "<p>"+str(v2)+"</p>" | |
return v2 |
Over a year, so I am betting you have found a workaround or simply just moved on.
But I believe the problem with your code lies in the way you have tried to override the render function.
The render() method takes in 5 parameters, causing some backward compatibility issues with older versions of Django.
def render(self, name, value, attrs=None, renderer=None):
Better later than never 😄
@nameisnot sorry I hadn't seen your comment earlier. @lanningspencer is probably right about this.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I tried the gist for my project but coming up with errors like "Type Error" render() got an unexpected keyword argument 'name'.
Background:
My Original Form class:
Field "unit_number" is an FK field to another model from where it inherits the
__str__()
value.With this line of approach I am able to disable the fields
complaint_short_desc
andcomplaint_long_text
. But the FK field "unit_number" is displayed as a normal drop down choice field which allows the user to select the choices available and change the value. I tried using theChoiceField
for the FK fieldunit_number
but I get an empty drop down widget.While searching I came across your gist but unable to implement it.
How I am trying to adopt your code:
The FK Read Only widget class:
Note: I had first tried to put my model name (which is complaint) but came up with error so I changed it back to your code with None.
Finally I modified my Form class as:
At this point I am getting an error saying (cited at the beginning):
I am using Django 2.0.6 / Python 3.6.4.
Can you provide a guidance as to what I am missing here?
Thanks.