【问题标题】:Django admin inline form with readonly old values and allowing to add new inline values具有只读旧值并允许添加新内联值的 Django 管理内联表单
【发布时间】:2015-01-15 03:50:05
【问题描述】:

我正在尝试解决这个问题,但由于某种原因,到目前为止每次尝试都失败了。我有两个简单的模型:问答:

class Question(models.Model):
    phoneID = models.CharField(max_length=255, editable=False)
    name = models.CharField(max_length=255, editable=False)
    phone = models.CharField(max_length=255, editable=False)
    message = models.TextField(editable=False)
    answered = models.DateTimeField(editable=False)
    created = models.DateTimeField(auto_now_add=True, default=datetime.utcnow())

class Answer(models.Model):
    question = models.ForeignKey(Question)
    message = models.TextField()
    created = models.DateTimeField(auto_now_add=True, default=datetime.utcnow())

由于某种原因,我无法弄清楚我应该将什么放入我的 admin.py 以将之前添加的内联答案列为只读,同时允许添加内联新答案。每次我设置 readonly_fields=('message') 时,我都无法添加新答案,因为消息 textarea 是只读的。

【问题讨论】:

标签: django django-admin


【解决方案1】:

好的,我明白你想要什么。为此,您可以创建一个特殊的小部件,该小部件将显示字段值,同时将是一个隐藏的输入。使用此小部件获取以前的答案:

from django.forms.widgets import Widget
from django.forms.utils import flatatt
from django.utils.html import format_html

class ReadOnlyInput(Widget):

    def render(self, name, value, attrs=None):
        if value is None:
            value = ''
        final_attrs = self.build_attrs(attrs, type='hidden',
                                       name=name, value=value)
        return format_html('<input{} />{}', flatatt(final_attrs), value)


class AnswerForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(AnswerForm, self).__init__(*args, **kwargs)
        if self.instance.pk:
            self.fields['message'].widget = ReadOnlyInput()


class AnswerInline(admin.TabularInline):
    form = AnswerForm
    model = Answer

【讨论】:

  • 其实这里的帖子就像我之前提到的 (stackoverflow.com/questions/18269366/…) 工作得很好。你的代码有什么区别?您的解决方案是否更有效?我只是在问,因为我仍然要完全理解这个框架。谢谢
  • 我的解决方案简单明了、防弹且不使用魔法。这就是 django 表单的工作方式。提到的答案使用_construct_form,这是BaseInlineFormSet 的私有方法(以下划线开头的方法是私有的,不应使用)。
  • 好答案。谢谢
  • 您也可以在不创建新小部件的情况下执行self.fields[field_name].disabled = True
  • @ArmanOrdookhani 如果您使用disabled = True,但添加新选择器时仍会禁用选择器。
【解决方案2】:

Django 1.7 允许您在管理内联中显示对象的属性。

class AnswerInline(admin.TabularInline):
    model = Answer
    fields = ('message', 'message_display', )
    readonly_fields=('message_display', )

    def message_display(self, obj):
        return obj.message

【讨论】:

  • 谢谢catavaran,我实际上学到了一些新东西。不幸的是,它仍然没有做我想要的。也许我没有让自己足够清楚。最后我有一个问题和几个答案显示内联。我希望所有已经存在的答案都是只读的(不可编辑)。最重要的是,我希望能够为内联表单添加一个新答案。但正是最后一步不起作用。它是或。如果我将旧答案设为只读并尝试添加新答案,则这些字段也只是只读的,因此我无法内联添加新答案。
  • 其实这个人也有同样的问题看这个问题stackoverflow.com/questions/18269366/…。但是他自己提出的解决方案对我不起作用。
【解决方案3】:

今天也有同样的问题。首先是尝试修改form,然后是get_readonly_fields,然后是其他许多东西。然后想起了这件优雅的事:

class MyInline(admin.StackedInline):
    def has_change_permission(self, request, obj=None):
        return False

【讨论】:

    猜你喜欢
    • 2014-05-15
    • 1970-01-01
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 2022-06-28
    • 2013-06-11
    • 1970-01-01
    相关资源
    最近更新 更多