Django - 如何在admin * changelist *界面的表格中创建一个单元格,只有在null时才能编辑? [英] Django - how can I make a cell in a table in the admin *changelist* interface editable only if it is null?

查看:256
本文介绍了Django - 如何在admin * changelist *界面的表格中创建一个单元格,只有在null时才能编辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我的数据可以在Django管理页面内联内嵌。但是,我只想要在每一行的一些字段列可编辑。这些列将针对每一行进行更改。基本上,如果某个单元格中的值为空,我希望显示一个下拉列表选项。如果它不为null,那么我不希望它是可编辑的,并且希望它是只读的。

I would like my data to be editable inline in the Django admin page. However, I only want some fields columns in each row to be editable. These columns will change for each row. Basically, I want a dropdown choice to be displayed if the value in a certain cell is null. If it is not null, then I don't want it to be editable and would like it to be readonly.

models.py

models.py:

class Size(models.Model):
    size = models.CharField(max_length=20, primary_key=True)

class Book(models.Model):
    title = models.CharField(max_length=100, primary_key=True)
    size = models.ForeignKey(Size, null=False)

class Pamphlet(models.Model):
    title = models.CharField(max_length=100, primary_key=True)
    size = models.ForeignKey(Size, null=True)
    book = models.ForeignKey(Book, null=True)

admin.py

class PamphletAdmin(admin.ModelAdmin):
    model = Pamphlet
    list_editable = ('size','book')
    list_display = ('title', 'size', 'book',)

    def get_changelist_form(self, request, **kwargs):
        return PamphletChangeListForm

forms.py

class PamphletChangeListForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(PamphletChangeListForm, self).__init__(*args, **kwargs)
        instance = kwargs.get('instance')
        if instance:
            self.fields['book'].queryset = Book.objects.filter(
                size=instance.size
            )
            if instance.size is not None:
                self.fields['size'].widget.attrs['readonly'] = 'readonly'

此设置对我而言无效。 size 显示为可更改列表形式的可编辑,即使它不为空。还有 - 我没有理解什么?

This setup is not working for me. The size shows as editable in the changelist form even when it is not null. Also - what have I failed to understand?

推荐答案

如果您的字段使用输入元素,例如 TextField ,将 readonly 属性添加到字段的小部件的在更改列表窗体的 __ init __ 方法中的attrs dict。这样的东西:

If your field uses an input element, such as a TextField, add the readonly attribute to the field's widget's attrs dict in the changelist form's __init__ method. Something like this:

class PamphletChangeListForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(PamphletChangeListForm, self).__init__(*args, **kwargs)
        instance = kwargs.get('instance')
        if instance:
            self.fields['book'].queryset = Book.objects.filter(
                size=instance.size
            )
            if instance.size is not None:
                self.fields['size'].widget.attrs['readonly'] = 'readonly'

不会保护您免受恶意用户伪造帖子数据 - 因此您需要进一步自定义您的管理员。但是如果您的管理员有恶意用户,则会遇到更大的问题。

That won't protect you against a malicious user faking post data - for that you'd need to customize your admin further. But if you have malicious users on your admin you have bigger problems.

如果您的字段使用选择您必须更改它 - 选择属性不具有只读作为支持的属性。相反,您将需要具有不变值的隐藏输入和文本表示,以便用户可以看到该设置。 Django不包括这样一个小部件,但你可以自己定义:

If your field uses a select element, you have to change it more - select attributes don't have readonly as a supported attribute. Instead, you'll want a hidden input with the unchanging value, and a text representation so the user can see what the setting is. Django does not include such a widget, but you can define your own:

class LabeledHiddenInput(forms.widgets.HiddenInput):
    def render(self, name, value, attrs=None):
        base_output = super(LabeledHiddenInput, self).render(name, value, attrs)
        if value:
            return base_output + unicode(value)
        else:
            return base_output

您可能需要更仔细的逃避甚至一些HTML格式化,这只是一个简单的例子。如果需要更多示例,请检查内置小部件的源代码。

You might need more careful escaping or even some HTML formatting, this is just a quick example. Check the source code for the built in widgets if you need more examples.

然后,您可以使用该小部件而不是默认选择:

Then you can use that widget instead of the default select:

        if instance.size is not None:
            self.fields['size'].widget = LabeledHiddenInput()

这篇关于Django - 如何在admin * changelist *界面的表格中创建一个单元格,只有在null时才能编辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆