如何过滤表单上的模型字段是外键而不是主外键

How do I filter a model field on a form that is a foreignkey but not the main foreignkey

我有一个 inlineformset_factory 是一组 ShoppingListItemForm

查看:

class ShoppingListItemForm(ModelForm):
    @property
    def __name__(self):
        return self.__class__.__name__

    def __init__(self, *args, **kwargs):

        if kwargs.get('instance'):

            theList = kwargs['instance']
            self.fields['category'] = forms.ChoiceField(choices=[(cat.id, cat.name) for cat in ListItemCategory.objects.filter(shoppinglist__id=theList.id)])

        return super(ShoppingListItemForm, self).__init__(self, *args, **kwargs)



    class Meta:
        model = ShoppingListItem
        fields = ('item', 'brand', 'quantity', 'current', 'category', 'size', )


@login_required
def shoppinglist(request, shoppinglist_id, pod_id):
    profile = request.user.get_profile()
    shoppinglist = get_object_or_404(ShoppingList, pk=shoppinglist_id)

    ListFormSet = inlineformset_factory(ShoppingList, ShoppingListItem, form=ShoppingListItemForm, extra=1, can_delete=True)

    myForms = ListFormSet(instance=shoppinglist)

...这很好用,除了 'category' 是 ShoppingListItem 的外键,我需要将表单上提供的 'category' 选项过滤为仅与 ListItemCategory 相关的选项'shoppinglist'。 'shoppinglist' 是 ListItemCategory 和 ShoppingListItem 的外键。

型号:

class ListItemCategory(models.Model):
    name = models.CharField(max_length=30, blank=True, null=True)
    shoppinglist = models.ForeignKey(ShoppingList)

class ShoppingListItem(models.Model):
    shoppinglist = models.ForeignKey(ShoppingList)
    category = models.ForeignKey(ListItemCategory, blank=True, null=True, default = None)
    item = models.CharField(max_length=200, blank=True, null=True)

class ShoppingList(models.Model):
    name = models.CharField(max_length=30, blank=True, null=True, default="Pod List")

...我认为没有必要将 'shoppinglist' 作为额外参数传递,因为它是作为表单实例传递的,但是添加了此初始化后,我呈现的模板什么也没有完全在表单集中。

还有什么建议吗?

您的问题是您不是 "initializing" 表单中的变量 shoppinglist_id def init

试试这个:

class ShoppingListItemForm(ModelForm):
    class Meta:
        model = ShoppingListItem
        fields = ('item', 'brand', 'quantity', 'current', 'category', 'size', )

    def __init__(self, *args, **kwargs):
        shoppinglist_id = kwargs.pop('shoppinglist_id', None)
        super(ShoppingListItemForm, self).__init__(*args, **kwargs)
        self.fields['category'].queryset = ListItemCategory.objects.filter(shoppinglist__id=shoppinglist_id)

你还应该编辑如何初始化表单:

ListFormSet = inlineformset_factory(ShoppingList, ShoppingListItem, form=ShoppingListItemForm(shoppinglist_id=shoppinglist.id), extra=1, can_delete=True)

所做的更改是下一个:

  1. shoppinglist_id 作为 kwarg 参数传递

...ShoppingListItemForm(shoppinglist_id=shoppinglist.id)

  1. 在您的表单中获取 kwarg 参数

    def __init__(self, *args, **kwargs): shoppinglist_id = kwargs.pop('shoppinglist_id', None)