【问题标题】:Filtering Model Instances In ModelForm Field在 ModelForm 字段中过滤模型实例
【发布时间】:2015-09-30 21:43:39
【问题描述】:

如果这个问题已经被另一个问题所涵盖,我深表歉意 - 我是 Django 的新手,现在可能与 Stack 上的许多其他问题一起盯着这个问题太久了..

使用 Django 1.8.2,我有一个显示用户列表的模型表单,我想从中排除当前用户(即您看不到自己)。我试图通过重写 init 方法来将当前用户从“to_user”列表中排除。我收到以下错误(“邀请没有 to_user”),我不明白。该字段不应该从模型中的 to_user ForeignKey 字段填充吗?

非常感谢您的帮助和时间 -

具体错误是:

我的模特是:

class Invitation(models.Model):
    from_user = models.ForeignKey(User, related_name="invitations_sent")
    to_user = models.ForeignKey(User, related_name="invitations_received", verbose_name="User to Invite", help_text="This is Help Text") # Verbose name is the form label for Foreigh Key vars
    message = models.CharField("Optional Message", max_length=300, blank=True) # Can add string for lavel, Setting blank=True means the field won't be required with ModelForm
    timestamp = models.DateTimeField(auto_now_add=True)

我的表单类是:

class InvitationForm(ModelForm):
    class Meta: # Class Meta sets the model class that the form needs to be auto-created for
        model = Invitation
        exclude = ['from_user']

    def __init__(self, user, **kwargs):
        super(InvitationForm, self).__init__(user, **kwargs)
        self.fields['to_user'].queryset = Invitation.objects.exclude(user=self.instance.to_user)

我的观点是:

@login_required
def new_invitation(request):
    if request.method == "POST":
        invitation = Invitation(from_user=request.user)
        form = InvitationForm(data=request.POST, instance=invitation)
        if form.is_valid():
            form.save()
        return redirect('user_home')
    else:
        form = InvitationForm(user=request.user)
    return render(request, "tictactoe/new_invitation.html", {'form' : form})

【问题讨论】:

  • 异常提到Invitation对象没有to_user集(该字段为空白)
  • 感谢您的帮助,karthikr。

标签: django django-models django-forms django-queryset modelform


【解决方案1】:

我的问题是尝试从 Invitation 模型构建一个查询集,该模型不包含我想要过滤的内容。也采纳了 Alasdair 的建议,关键是将 User 模型导入到我的 forms.py 文件中,然后在 User 模型上构建查询集,从视图中传入登录用户。

我的 ModelForm 现在看起来像:

class InvitationForm(ModelForm):

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super(InvitationForm, self).__init__(*args, **kwargs)
        self.fields['to_user'].queryset = User.objects.exclude(id=user.id)

    class Meta:
        model = Invitation
        exclude = ['from_user']

从视图实例化:

@login_required
def new_invitation(request):
    if request.method == "POST":
        invitation = Invitation(from_user=request.user)
        form = InvitationForm(user=request.user, data=request.POST, instance=invitation)
        if form.is_valid():
            form.save()
            return redirect('user_home')
    else:
        form = InvitationForm(user=request.user)
    return render(request, "tictactoe/new_invitation.html", {'form' : form})

谢谢大家的帮助。

【讨论】:

    【解决方案2】:

    不清楚您为什么更改了__init__ 方法的签名。您不应将用户传递给 super() 调用。由于您没有在任何地方使用user,并且在实例化表单时也没有传递它,所以我会删除它。

    其次,您可能想要排除 instance.from_user 而不是 instance.to_user。

    class InvitationForm(ModelForm):
        def __init__(self, *args, **kwargs):
            super(InvitationForm, self).__init__(*args, **kwargs)
            self.fields['to_user'].queryset = Invitation.objects.exclude(user=self.instance.from_user)
    

    【讨论】:

    • 感谢您的帮助,阿拉斯代尔。
    • 很高兴你明白了:)
    猜你喜欢
    • 2020-02-04
    • 2018-10-28
    • 2020-03-19
    • 2015-09-06
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多