使用ManyToMany关系的Django表单错误- TypeError:字段“id”需要一个数字,但得到了< Profile: user1>

k5ifujac  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(128)

我正在做一个推荐应用程序,用户可以向一个或多个用户推荐电影/节目/书籍。表单设置为显示所有用户的列表,您可以选中要向其发送建议的用户旁边的框,但当我在选中用户名旁边的框后点击表单上的“提交”时,我得到了这个错误(Field 'id' expected a number but got <Profile: user1>),我不知道我哪里出错了。与此相关的大多数其他问题都是在他们的模型中使用ForeignKey而不是ManyToManyField

models.py:

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    follows = models.ManyToManyField( 
        'self',
        related_name='followed_by',
        symmetrical=False,
        blank=True,
    )

    def __str__(self):
        return self.user.username
    
class Recommendation(models.Model):
    user = models.ForeignKey(
        User, related_name="recs", on_delete=models.DO_NOTHING
    )
    recipients = models.ManyToManyField(
        User, related_name="received_recs", symmetrical=False, blank=True
    )
    title = models.CharField(max_length=300)
    description = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return (
            f"{self.user} "
            f"({self.created_at:%y-%m-%d %H:%M}): "
            f"{self.title}"
        )

views.py:

from django.shortcuts import render, redirect
from .models import Profile, Recommendation
from .forms import RecForm

def dashboard(request):
  all_recs = Recommendation.objects.all()
  if request.method == "POST":
    form = RecForm(request.POST or None)
    if form.is_valid():
      rec = form.save(commit=False)
      rec.user = request.user
      rec.save()
      form.save_m2m()
      return redirect("watchthisshit:dashboard")
  form = RecForm()
  return render(request, "watchthisshit/dashboard.html", {
    "all_recs": all_recs,
    "form": form
  })

forms.py:

from django import forms
from django.db.models.base import Model
from .models import Profile, Recommendation

class RecForm(forms.ModelForm):
  title = forms.CharField(required=True)
  description = forms.CharField(widget=forms.widgets.Textarea(
    attrs={
      "placeholder": "You don't have to write a description, but it would be pretty cool if you did...",
      "class": "textarea is-success is-medium"
    }
  ), label="",)
  recipients = forms.ModelMultipleChoiceField(
    queryset=Profile.objects.all(),
    widget=forms.CheckboxSelectMultiple
  )

  class Meta:
    model = Recommendation
    fields = ["title", "description", "recipients"]
    exclude = ("user", )

我认为问题可能在于如何将它传递给ModelMultipleChoiceField,因此我尝试在www.example.com中执行以下操作forms.py:

recipients = forms.ModelMultipleChoiceField(
    queryset=Profile.objects.all().values_list('id', 'user'),
    widget=forms.CheckboxSelectMultiple
  )

然而,这只是返回一个元组(1,1),我不能访问名称。它实际上也没有保存任何东西。

ukqbszuj

ukqbszuj1#

因为在Recommendation中,您将recipients设置为与User对象相关。但是,在您的表单中,您使用Profile来填充您的选择,这是一个小错误。
因此,当您尝试.save_m2m时,它会崩溃,因为字段需要User而不是Profile,快速修复:
forms.py

class RecForm(forms.ModelForm):
    title = ...
    description = ...
    recipients = forms.ModelMultipleChoiceField(
        queryset=User.objects.all(), widget=forms.CheckboxSelectMultiple
    )

    class Meta:
        ...

略有改进

因此User不能将自己标记为收件人。我们可以覆盖Form __init__方法,并通过提供初始值,我们可以从QuerySet中排除current user
forms.py

class RecForm(forms.ModelForm):
    title = ...
    description = ...
    recipients = forms.ModelMultipleChoiceField(
        queryset=None, widget=forms.CheckboxSelectMultiple
    )

    class Meta:
        ...

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        current_user_id = self.initial.get('user', None)
        self.fields["recipients"].queryset = User.objects.exclude(pk=current_user_id)

views.py

def dashboard(request):
    all_recs = Recommendation.objects.all()

    if request.method == "POST":
        ...
    form = RecForm(initial={"user": request.user.id})
    return render(
        request, "watchthisshit/dashboard.html", {"all_recs": all_recs, "form": form}
    )

相关问题