【问题标题】:How to save m2m field on Django with commit=False?如何使用commit = False在Django上保存m2m字段?
【发布时间】:2017-06-24 13:47:17
【问题描述】:

我希望能够保存 m2m 字段,但我遇到了一个问题,我遇到了这个错误:

ValueError: : "..." 需要有一个字段 "id" 的值才能使用这种多对多关系。

这是我的 models.py

class Font(models.Model):
    name = models.CharField(max_length=255)
    ...

class UserInfo(models.Model):
    organisation = models.CharField(max_length=255)
    font = models.ManyToManyField(Font)
    ...

我将 modelForm 用于多对多领域。我用 ajax 得到了我的价值观,这是(pdb) request.POST 上的样子:

<QueryDict: {'fonts': ['2', '5', '6'], 'organisation': ['COMPANY'], 'csrfmiddlewaretoken': ['...']}>

'fonts' 中的内容是Font 的 id。

views.py

...
    save_it = form.save(commit=False)
    save_it.organisation = request.POST.get('organisation')

    for font in request.POST.getlist('fonts'):
        fonts = Font.objects.filter(id=font)
        save_it.font = fonts.first().id #error on save_it.font

    save_it.save()
    save_it.save_m2m()
...

forms.py

class UserInfoForm(forms.ModelForm):
    class Meta:
        model = UserInfo
        fields = ['organisation', 'fonts']

我做错了什么?

【问题讨论】:

  • 简单地执行 form.save() 会出现什么问题?你能用回溯显示错误吗?还是没有错误,但也没有创建关系?
  • @Melvyn 它保存除了 m2m 字段之外的所有内容,没有关系。错误出现在 save_m2m()
  • 表单的“字体”字段生成什么?它会生成表单集吗?如果是这样,您的 ajax 不会传输它是 management form
  • @Melvyn 表单 m2m 字段采用这种格式,'fonts': ['2', '5', '6'] 这就是为什么我使用commit=False 能够获取每个对象的idsave() 它们。

标签: python django django-views


【解决方案1】:

要继续前进,我认为最好从表单中删除“字体”字段。它不知道如何处理它,并且考虑到字体是如何传输的,您可能没有使用为它生成的 HTML。

您的视图代码将是这样的:

def form_valid(self, form):
    obj = form.save()
    for font_id in request.POST.getlist('fonts'):
        obj.font.add(Fonts.objects.get(id=font_id))

【讨论】:

  • obj.font.add(Fonts.objects.get(id=font_id).first().id)save() 之后是我需要的。只是一个小修正,obj.font 不期望查询集。
  • 但是 get() 不返回一个。你做了 filter() 吗?
  • 是的,我做到了。 Django 要求我使用对象 ID 或名称中的任何一种方式
  • 这里是gory details。但 id 的工作也是。任何对你来说更易读的东西。
猜你喜欢
  • 2012-11-06
  • 2010-11-14
  • 2018-09-24
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-25
  • 2013-02-05
相关资源
最近更新 更多