我有一个小问题,我想我一定很常见。
以下是非常常见的问题:

class Ownable(models.Model):
    user = models.ForeignKey(django.contrib.auth.models.User)

    class Meta:
        abstract = True


class Bowl(Ownable):
    pass


class Pea(Ownable):
    bowl = models.ForeignKey(bowl)

关系是:User [1:n] Bowl
User [1:n] Pea
Bowl [1:n] Pea
现在,当我想创建一个新的Pea时,我还需要将它分配给Bowl这样:
def create_new_pea(request):
    PeaFrom = inlineformset_factory(django.contrib.auth.models.User, Pea)
    return render(request, 'app/pea/create.html', {'formset': PeaFrom()})

在这个过程中,我如何能够将一个QuerySet传递到bowl-字段,因为用户只能将bean放入自己的碗中。
我很乐意听取你的建议。我试图为formset工厂创建一个自定义表单,但我需要request实例来了解当前用户。

最佳答案

一个简单的方法是在实例化表单集之后执行。

def create_new_pea(request):
    PeaFormset = inlineformset_factory(django.contrib.auth.models.User, Pea)
    formset = PeaFormset(instance=request.user)
    for form in formset:
        form.fields['bowl'].queryset = request.user.bowl_set.all()
    return render(request, 'app/pea/create.html', {'formset': formset}

我认为可以将此行为构建到自定义Formset类中,覆盖_construct_forms方法:
class UserLimitedFormset(BaseInlineFormset):
    def _construct_forms(self):
        super(UserLimitedFormset, self)._construct_forms()
        for form in self:
            form.fields['bowl'].queryset = self.instance.bowl_set.all()

PeaFormset = inlineformset_factory(django.contrib.auth.models.User, Pea, formset=UserLimitedFormset)

要使用回调,我认为在创建表单集之前需要一个闭包或functools.partial来记录用户。可能是这样,尽管它还未经测试,而且我对闭包也很生疏:
def create_new_pea(request):
    user = request.user
    def set_queryset(f, **kwargs):
        formfield = f.formfield(**kwargs)
        if f.name == 'bowl':
            formfield.queryset = user.bowl_set.all()
        return formfield
    PeaFormset = inlineformset_factory(django.contrib.auth.models.User, Pea, formfield_callback=set_queryset)

09-16 05:06