【问题标题】:Why 'model' object is not iterable?为什么“模型”对象不可迭代?
【发布时间】:2016-12-25 21:09:11
【问题描述】:

我正在尝试在我的管理面板中添加一个无线电选择。我使用多对多字段来连接另一个模型(背景)的对象。

我现在拥有的: 收音机选择在这里并且可以在管理面板上使用,但是当我继续并保存更改时出现此错误:'Background' object is not iterable

如何保存信息并保持选中状态?

MyApp/models.py

class Background(models.Model):
    bk_color = models.CharField(max_length=20)
    ...

class FormOne(models.Model):
    name = models.CharField(max_length=40)
    background = models.ManyToManyField(Background, blank=True)
    ...

MyApp/forms.py

class FormOneForm(forms.ModelForm):
    class Meta:
        model = FormOne
        fields = ['name', 'background']

    background = forms.ModelChoiceField(widget=forms.RadioSelect, queryset=Background.objects.all(), required=False)

MyApp/admin.py

class FormOneAdmin(ModelAdmin):
    fields = ['name', 'background']
    form = FormOneForm


site.register(Background)
site.register(FormOne, FormOneAdmin)

我无法调试问题,很高兴知道问题出在哪里以及如何解决?

编辑:

添加了回溯:

Traceback:
File "C:\Python34\lib\site-packages\django\core\handlers\base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python34\lib\site-packages\django\contrib\admin\options.py" in wrapper
  618.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Python34\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\django\contrib\admin\sites.py" in inner
  233.             return view(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\django\contrib\admin\options.py" in change_view
  1521.         return self.changeform_view(request, object_id, form_url, extra_context)
File "C:\Python34\lib\site-packages\django\utils\decorators.py" in _wrapper
  34.             return bound_func(*args, **kwargs)
File "C:\Python34\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\django\utils\decorators.py" in bound_func
  30.                 return func.__get__(self, type(self))(*args2, **kwargs2)
File "C:\Python34\lib\contextlib.py" in inner
  30.                 return func(*args, **kwds)
File "C:\Python34\lib\site-packages\django\contrib\admin\options.py" in changeform_view
  1470.                 self.save_related(request, form, formsets, not add)
File "C:\Python34\lib\site-packages\django\contrib\admin\options.py" in save_related
  1102.         form.save_m2m()
File "C:\Python34\lib\site-packages\django\forms\models.py" in save_m2m
  102.                 f.save_form_data(instance, cleaned_data[f.name])
File "C:\Python34\lib\site-packages\django\db\models\fields\related.py" in save_form_data
  2603.         setattr(instance, self.attname, data)
File "C:\Python34\lib\site-packages\django\db\models\fields\related.py" in __set__
  1266.         value = tuple(value)

Exception Type: TypeError at /admin/multistepform/formone/75/
Exception Value: 'Background' object is not iterable

【问题讨论】:

  • 请发布完整的堆栈跟踪。
  • @Jean-FrançoisFabre 我添加了轨迹。

标签: python django django-forms django-admin


【解决方案1】:

您不能使用 radio widget 来创建 多对多 关系,因为 django 需要一个 background id 数组(这就是 django 在您的堆栈跟踪中抱怨的)而不是单个background id 当您将数据发布到 FormOneAdmin 添加视图时。

你可以把ModelChoiceField这行注释掉,你就可以让它工作了。

class FormOneForm(forms.ModelForm):
    class Meta:
        model = FormOne
        fields = ['name', 'background']

    # background = forms.ModelChoiceField(widget=forms.RadioSelect, queryset=Background.objects.all(), required=False)

或者如果您仍然需要让零个或一个Background 对象绑定到FormOne 对象,您应该使用ForeignKey 而不是ManyToManyField。代码如下所示:

class FormOne(models.Model):
    name = models.CharField(max_length=40)
    # background = models.ManyToManyField(Background, blank=True)
    background = models.ForeignKey(Background, blank=True) # <-- use foreign key instead


class FormOneForm(forms.ModelForm):
    class Meta:
        model = FormOne
        fields = ['name', 'background']

    background = forms.ModelChoiceField(widget=forms.RadioSelect, queryset=Background.objects.all(), required=False)


class FormOneAdmin(admin.ModelAdmin):
    fields = ['name', 'background']
    form = FormOneForm

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-22
    • 2019-10-15
    • 2021-03-01
    • 2021-05-16
    • 1970-01-01
    • 2018-05-18
    • 2020-04-09
    相关资源
    最近更新 更多