在ModelChoiceField中限制选项

1 投票
1 回答
684 浏览
提问于 2025-04-16 00:48

我刚接触Python和Django,所以这个问题可能很简单,但我就是搞不定。基本上,我有一个模型,这个模型里有两个用户类型的外键。我正在构建一个表单,想要根据另一个字段来移除一个ModelChoiceField中的选项。我希望用户在表单中不能选择自己。

我的代码如下。

Models.py

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

class Deuda(models.Model):
    ESTADOS = (("S", "Sin pagar"), ("P", "Pagada"), ("PC", "Pagada (Confirmada)"))

    propietario = models.ForeignKey(User, verbose_name="Propietario", related_name="propietario_deuda")
    adeudado = models.ForeignKey(User, verbose_name="Adeudado", related_name="adeudado_deuda")
    cantidad = models.FloatField("Cantidad")
    descripcion = models.TextField("Descripcion")
    estado = models.CharField(max_length=2, choices=ESTADOS)

    def __str__(self):
        return self.descripcion

forms.py

from django import forms
from housemanager.iou.models import Deuda
from django.contrib.auth.models import User

class DeudaForm(forms.ModelForm):

    class Meta:
        model = Deuda
        exclude = ('propietario',)

    def __init__(self, propietario):
        d = Deuda()
        d.propietario = propietario
        forms.ModelForm.__init__(self, instance=d)

    adeudado = forms.ModelChoiceField(queryset=User.objects.exclude(pk=d.propietario.pk))

views.py的摘录

[...]
form = DeudaForm(request.user)

我的想法是把用户传递给表单,这样它就可以定义一个不包含自己的ModelChoiceField。我的代码不工作是因为在设置'adedado'时,d不在作用域内。我相信有很多方法可以实现这个目标,欢迎随意修改我的设计。

最终代码:

from django import forms
from housemanager.iou.models import Deuda
from django.contrib.auth.models import User

class DeudaForm(forms.ModelForm):

    class Meta:
        model = Deuda
        exclude = ('propietario',)

    def __init__(self, propietario):
        d = Deuda()
        d.propietario = propietario
        forms.ModelForm.__init__(self, instance=d)
        self.fields['adeudado'].queryset = User.objects.exclude(pk=propietario.pk)

1 个回答

1

试着把它放在表单的 __init__ 方法里:

class DeudaForm(forms.ModelForm):

    class Meta:
        model = Deuda
        exclude = ('propietario',)

    def __init__(self, propietario):
        forms.ModelForm.__init__(self)
        self.fields['adeudado'].queryset = User.objects.exclude(pk=d.propietario.pk)

撰写回答