【问题标题】:Problem Saving ManytoManyField using ModelForm Django使用 ModelForm Django 保存 ManytoManyField 的问题
【发布时间】:2020-11-15 18:32:57
【问题描述】:

models.py

from django.db import models
from django.contrib.auth.models import User


class Elements(models.Model):
    element = models.CharField(max_length=10, unique=True)

    def __str__(self):
        return self.element


class Hero(models.Model):
    added = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    name = models.CharField(max_length=10, unique=True)
    element = models.ManyToManyField(Elements, blank=True)

    def __str__(self):
        return self.name

forms.py

from django import forms
from .models import Elements, Hero


class HeroForm(forms.ModelForm):
    class Meta:
        model = Hero
        exclude = [
            'added'
        ]
        widgets = {
            'element': forms.CheckboxSelectMultiple
        }

views.py

from django.shortcuts import render
from .forms import HeroForm


def home(request):
    form = HeroForm(request.POST or None)
    if form.is_valid():
        hero = form.save(commit=False)
        hero.added = request.user
        hero.save()


        form = HeroForm()

    return render(request, 'home.html', {'form': form})

每当我尝试在保存之前像上面在views.py 中显示的那样操作模型表单时,元素的(manytoamyfield)数据会自动设置为null。但是,如果我将表单保存为用户选择的已保存元素的数据。

如何在保存表单之前操作表单数据并保持多字段数据原样?

提前致谢

【问题讨论】:

    标签: django django-forms manytomanyfield


    【解决方案1】:

    如果你使用commit=False,那么ModelForm就不能保存多对多关系,这样对象就没有主键了。

    您可以简单地更改表单中的实例之前保存表单:

    from django.contrib.auth.decorators import login_required
    
    @login_required
    def home(request):
        if request.method == 'POST':
            form = HeroForm(request.POST)
            if form.is_valid():
                form.instance.added = request.user
                form.save()  # no commit=False
                form = HeroForm()
        else:
            form = HeroForm()
        return render(request, 'home.html', {'form': form})

    注意:如果 POST 请求成功,请发送redirect [Django-doc] 实施Post/Redirect/Get pattern [wiki]。 这样可以避免在用户刷新时发出相同的 POST 请求 浏览器。


    注意:通常使用settings.AUTH_USER_MODEL [Django-doc] 引用用户模型比直接使用User model [Django-doc] 更好。更多信息可以查看referencing the User model section of the documentation


    注意:您可以使用 @login_required decorator [Django-doc].

    【讨论】:

      猜你喜欢
      • 2017-06-29
      • 1970-01-01
      • 2012-07-03
      • 2018-01-11
      • 2012-07-23
      • 2021-01-26
      • 2010-10-31
      • 2011-01-12
      • 2020-05-11
      相关资源
      最近更新 更多