Django |object< title>(None)&gt;”需要有字段“id”的值,然后才能使用这种多对多关系

2nc8po8w  于 2023-06-25  发布在  Go
关注(0)|答案(2)|浏览(134)

我在使用www.example.com时出现错误form.save(commit=False),我不知道我做错了什么。
我的观点是这样的:

views.py

def make_electable(request, election_id):
    election = get_object_or_404(CommissionElection, id=election_id)
    if request.method == 'POST':
        form = MakeElectable(request.POST)
        if form.is_valid():
            electable = form.save(commit=False)
            electable.election.set(election)
            form.save()

forms.py

class MakeElectable(forms.ModelForm):
    class Meta:
          model = ElectablePerson
          fields = ['commission',]
    commission = forms.ModelChoiceField(queryset=Commissie.objects.all(), widget=forms.RadioSelect())

models.py

class CommissionElection(models.Model):
    title = models.CharField(max_length=64)
    commission = models.ManyToManyField(Commissie)
    electable_time = DateRangeField()
    voting_time = DateRangeField()

class ElectablePerson(models.Model):
    commission = models.CharField(max_length=128)
    election = models.ManyToManyField(CommissionElection)

我得到的错误是:
“<ElectablePerson:ElectablePerson对象(None)>”需要有字段“id”的值,然后才能使用此多对多关系。
我不明白为什么对象是None。我怀疑这和很多人的事有关。

83qze16e

83qze16e1#

多对多字段是一个使用'id_electable,id_election'作为键的表,其中commit=false,你不持久化,这给你没有id。下面的代码应该可以解决你的问题。

if form.is_valid():
    electable = form.save()
    electable.election.add(election)

另请参阅https://docs.djangoproject.com/en/dev/ref/models/relations/#django.db.models.fields.related.RelatedManager.add了解多对多关系。

ig9co6j1

ig9co6j12#

如果您链接的两个对象中有一个尚未在数据库中创建,则无法添加或设置多对多字段,因为对象需要令牌才能彼此链接,因此:

def make_electable(request, election_id):
    election = get_object_or_404(CommissionElection, id=election_id)
    if request.method == 'POST':
        form = MakeElectable(request.POST, request.FILES)
        if form.is_valid():
            electable = form.save()
            electable.election.set(election)
            return redirect('name-of-some-view')
    # …

注意:通常使用**.save(…)方法[Django-doc]保存表单时,最好不要使用commit=False:这将避免保存多对多关系,因为只有在提交了项目时才能保存这些关系。通常,最好修改表单中 Package 的.instance。有关更多信息,请参阅my article[Django-antippaterns]
注意:虽然大多数表单不处理媒体文件,但最好还是将
request.FILES**[Django-doc]传递给表单,这样如果您稍后添加额外的媒体字段,所有使用该表单的视图都会正确处理文件。

相关问题