Django:管理中的 MultipleChoiceField 可以继承以前保存的值

发布于 2024-09-26 04:11:38 字数 1842 浏览 6 评论 0原文

我无法在管理员的模型表单中继承之前选择的项目。 我想使用 forms.CheckboxSelectMultiple 小部件,因为这是此用例中最简单的 UI。它的作用是在保存时存储值。但是,当编辑先前保存的项目时,先前在此字段中保存的值不会反映在小部件中。

UI 示例:

alt text

发布后(编辑该项目,将其返回空白):

alt text

但是,当编辑项目时不使用小部件而是使用常规 CharField 时,它看起来像:

alt text

那么由于某种原因,复选框小部件没有表示这些值?

简化设置,models.py

POST_TYPES = (
    ('blog',      'Blog'),
    ('portfolio',     'Portfolio'),
    ('beeldbank',     'Beeldbank'),
)

class Module(models.Model):
    title         =   models.CharField(max_length=100, verbose_name='title')        
    entriesFrom     =   models.CharField(max_length=100)

    def __unicode__(self):
       return self.title

forms.py:admin.py

class ModuleForm(forms.ModelForm):
    entriesFrom = forms.MultipleChoiceField(
            choices=POST_TYPES, 
            widget=CheckboxSelectMultiple, 
            label="Pull content from", 
            required=False,
            show_hidden_initial=True) 

    class Meta:
        model = Module

    def __init__(self, *args, **kwargs):
        super(ModuleForm, self).__init__(*args, **kwargs)

        if kwargs.has_key('instance'):
            instance = kwargs['instance']
            self.fields['entriesFrom'].initial = instance.entriesFrom

            logging.debug(instance.entriesFrom)

这是我的

class ModuleAdmin(admin.ModelAdmin):
    form = ModuleForm

因此,当编辑以前保存的项目并选择“博客”时,init 上的调试会返回 self.fields[' 上的正确值itemsFrom'] ([u'blog',]),但它没有反映在管理中的复选框中(没有任何内容显示为选中)。

edit

更新了ModuleForm类以传递初始值,但仍然没有预先填充任何内容,而初始值中有一些值(“[u'blog']”)。

I am having troubles to carry over previously selected items in a ModelForm in the admin.
I want to use the forms.CheckboxSelectMultiple widget since that is the most straightforward UI in this usecase. It works as far that when saving, the values are stored. But when editing the previously saved item, the values previously saved in this field are not reflected in the widget.

UI Example:

alt text

After posting (editing that item, returns it blank):

alt text

However, when not using the widget but a regular CharField when editing the item it looks like:

alt text

So for some reason the values are not represented by the checkbox widget?

Here's my simplified setup, models.py

POST_TYPES = (
    ('blog',      'Blog'),
    ('portfolio',     'Portfolio'),
    ('beeldbank',     'Beeldbank'),
)

class Module(models.Model):
    title         =   models.CharField(max_length=100, verbose_name='title')        
    entriesFrom     =   models.CharField(max_length=100)

    def __unicode__(self):
       return self.title

forms.py:

class ModuleForm(forms.ModelForm):
    entriesFrom = forms.MultipleChoiceField(
            choices=POST_TYPES, 
            widget=CheckboxSelectMultiple, 
            label="Pull content from", 
            required=False,
            show_hidden_initial=True) 

    class Meta:
        model = Module

    def __init__(self, *args, **kwargs):
        super(ModuleForm, self).__init__(*args, **kwargs)

        if kwargs.has_key('instance'):
            instance = kwargs['instance']
            self.fields['entriesFrom'].initial = instance.entriesFrom

            logging.debug(instance.entriesFrom)

admin.py

class ModuleAdmin(admin.ModelAdmin):
    form = ModuleForm

So when editing a previously saved item with say 'blog' selected, debugging on init returns me the correct values on self.fields['entriesFrom'] ([u'blog',]), but its not reflected in the checkboxes (nothing is shown as selected) in the admin.

edit

updated the ModuleForm class to pass on initial values, but nothing still gets pre-populated whilst there are a few values in the initial value ("[u'blog']").

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

北方的韩爷 2024-10-03 04:11:38

解决方案:

用整数而不是字符串设置选项。

POST_TYPES = (
    (1,     'Blog'),
    (2,     'Portfolio'),
    (3,     'Beeldbank'),
)

该死,这不值得打破我的头骨。

Solution:

Setting the choices by a integer, instead of a string.

POST_TYPES = (
    (1,     'Blog'),
    (2,     'Portfolio'),
    (3,     'Beeldbank'),
)

Damn, that wasn't worth breaking my skull over.

伤感在游骋 2024-10-03 04:11:38

可能不正确,但对于我的用例,我不想用整数替换这些值(根据接受的答案)。这是通过一些尝试和错误以及对 Django 内部进行大量单步调试而实现的。对我有用,但是 YMMV:

from django.forms.widgets import (
    CheckboxSelectMultiple as OriginalCheckboxSelectMultiple,
)

class CheckboxSelectMultiple(OriginalCheckboxSelectMultiple):
    def optgroups(self, name, value, attrs=None):
        # values come back as e.g. `['foo,bar']`, which we don't want when inferring "selected"
        return super().optgroups(name, value[0].split(","), attrs)

Might not be correct, but for my usecase, I did not want to replace the values with integers (as per the accepted answer). This was arrived at by a smidge of trial-and-error, and a lot of stepping through Django internals. Works for me, but YMMV:

from django.forms.widgets import (
    CheckboxSelectMultiple as OriginalCheckboxSelectMultiple,
)

class CheckboxSelectMultiple(OriginalCheckboxSelectMultiple):
    def optgroups(self, name, value, attrs=None):
        # values come back as e.g. `['foo,bar']`, which we don't want when inferring "selected"
        return super().optgroups(name, value[0].split(","), attrs)
ま昔日黯然 2024-10-03 04:11:38

也许我不完全理解你的问题,但看来你可以简化一点。使用 ModelForms,我认为您没有必要重写表单中的_init_。试试这个,看看你是否得到了你想要的行为。

models.py

class Module(models.Model):
    POST_TYPES = (
        ('blog', 'Blog'),
        ('portfolio', 'Portfolio'),
    )

    title        =   models.CharField(max_length=100, verbose_name='title')        
    entriesFrom  =   models.CharField(max_length=100, verbose_name='Pull content from', choices=POST_TYPES, blank=True)

    def __unicode__(self):
       return self.title

forms.py

class ModuleForm(forms.ModelForm):
    class Meta:
        model = Module

admin.py

from django.contrib import admin
admin.site.register(models.Module)

如果我的答案不是您想要的,请尝试澄清您的问题,我会看看是否可以帮助您。

Maybe I'm not understanding your question completely, but it seems like you could simplify a little. Using ModelForms, I don't think any of your overriding the _init_ in your form is necessary. Try this and see if you get your desired behavior.

models.py

class Module(models.Model):
    POST_TYPES = (
        ('blog', 'Blog'),
        ('portfolio', 'Portfolio'),
    )

    title        =   models.CharField(max_length=100, verbose_name='title')        
    entriesFrom  =   models.CharField(max_length=100, verbose_name='Pull content from', choices=POST_TYPES, blank=True)

    def __unicode__(self):
       return self.title

forms.py

class ModuleForm(forms.ModelForm):
    class Meta:
        model = Module

admin.py

from django.contrib import admin
admin.site.register(models.Module)

If my answer isn't what you're looking for, try clarifying your question and I'll see if I can help you out.

爱情眠于流年 2024-10-03 04:11:38

您可以使用此功能来删除字符串标记

from ast import literal_eval

literal_eval(value)

you can use this function to remove string mark

from ast import literal_eval

literal_eval(value)
眼泪淡了忧伤 2024-10-03 04:11:38

我遇到了这个问题,我的更改没有影响保存。
我在 model 中使用 CharField,但在 forms.py 中使用;

class ModuleForm(forms.ModelForm):
    my_field = forms.MultipleChoiceField(
            choices=POST_TYPES, 
            widget=CheckboxSelectMultiple,
            required=False,) 

    def __init__(self, *args, **kwargs):
        super(ModuleForm, self).__init__(*args, **kwargs)
        if kwargs.get('instance'):
            self.initial['my_field'] = eval(self.initial['my_field'])

这个表单解决方案在 Django Admin 上的 MultipleChoiceField 上对我有用。

I faced this issue, my changes haven't affected on save.
I use CharField in model, but in forms.py;

class ModuleForm(forms.ModelForm):
    my_field = forms.MultipleChoiceField(
            choices=POST_TYPES, 
            widget=CheckboxSelectMultiple,
            required=False,) 

    def __init__(self, *args, **kwargs):
        super(ModuleForm, self).__init__(*args, **kwargs)
        if kwargs.get('instance'):
            self.initial['my_field'] = eval(self.initial['my_field'])

This form solution worked for me on MultipleChoiceField on Django Admin.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文