我正在为我的模型创建一个编辑视图,该视图具有对另一个表的引用。 我正在使用的模型如下所示:
class SkillSet(models.Model):
SKILL_LEVEL_CHOICES = (
(0, 'None'),
(1, 'Basic'),
(2, 'User'),
(3, 'Advanced'),
)
rating = models.ForeignKey(Rating, on_delete=models.CASCADE)
skill = models.ForeignKey(Skill)
skillLevel = models.IntegerField(choices = SKILL_LEVEL_CHOICES, default = 0)
notes = models.TextField(null=True, blank=True)
我为此创建了一个表单,您可以在此处看到:
class SkillSetEditForm(forms.ModelForm):
class Meta:
model = SkillSet
fields = [
"skill",
"skillLevel",
"notes"
]
labels = {
'skill': ('Skill'),
'skillLevel': ('Skill Level'),
'notes': ('Notes'),
}
然后我把它放在我的视图中:
{% for skillForm in skillForms %}
<tr class="nivEdit" style="display:none;">
<td>{{ skillForm.skill }}</td>
<td>{{ skillForm.skillLevel }}</td>
<td>{{ skillForm.notes}}</td>
</tr>
{% endfor %}
最终结果看起来不错,但我不希望我的用户能够编辑技能本身,只需要编辑级别和注释。我可以获得值,但这只是技能模型的基础ID。有没有办法让我从下拉列表中选择显示的文字?我可以用jquery / javascript做到这一点,但它会变得非常混乱,我希望在django中已经有了解决方案。
答案 0 :(得分:0)
如果您不希望用户设置级别,只需将其从SkillSetEditForm.fields
中删除即可。您必须自己在视图中添加它或在模型中设置为null = True, blank = True
。
如果您想显示技能名称而不是ID,则应将__unicode__
方法添加到Skill
模型中(但由于您从表单中删除它,因此无关紧要)。< / p>
如果您仍需要表单中的此字段,则可以使用Django 1.9+字段选项disabled
:https://docs.djangoproject.com/en/1.9/ref/forms/fields/#disabled
您可以在SkillSetEditForm
课程中尝试类似的内容:
def __init__(self, *args, **kwargs):
super(SkillSetEditForm, self).__init__(*args, **kwargs)
self.fields['skill'].disabled = True
答案 1 :(得分:0)
我试图将模型中的某些字段转换为只读字段时遇到了类似的问题。据我所知,没有内置的方式来处理这个优雅。您可以从表单中完全省略skill
字段,并通过在模板中呈现模型实例的相应字段来显示相关信息。作为一个替代品,我将以下mixin用于我的表单类:
class ReadonlyMixin(object):
def __init__(self, **kwargs):
super(ReadonlyMixin, self).__init__(**kwargs)
self.readonly_fields = self.get_readonly_fields()
self.disable_readonly_fields()
def get_readonly_fields(self):
return []
def disable_readonly_fields(self):
for field_name in self.readonly_fields:
field = self.fields[field_name]
field.required = False
field.widget.attrs.update({'readonly': True})
if isinstance(field, forms.ModelChoiceField):
selected = getattr(self.instance, field_name, None)
pk = selected.pk if selected else None
field.queryset = field.queryset.filter(pk=pk)
def clean(self):
self.clean_readonly_fields()
def clean_readonly_fields(self):
for field_name in self.readonly_fields:
if field_name in self.fields.keys():
self.cleaned_data[field_name] = getattr(self.instance, field_name)
这会将readonly
属性附加到get_readonly_fields
返回的字段,以便无法在浏览器中编辑相应的输入。它还限制所选输入的选择输入中的选择。为了防止用户通过操作html代码并将其发送回服务器来编辑只读字段,clean_readonly_fields
将使用模型实例的相应数据替换从客户端接收的数据。
像这样使用mixin:
class SkillSetEditForm(ReadonlyMixin, forms.ModelForm):
...
def get_readonly_fields(self):
return ['skill']