2

ちょっとした問題が発生しましたが、これはよくあることだと思いました。非常に一般的に説明されている問題は次のとおりです。

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] BowlUser [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、フィールドに a を渡すことができます。bowl

提案をいただければ幸いです。formset-factory のカスタム フォームを作成しようとしましたrequestが、現在のユーザーを知るためにインスタンスが必要です。

4

2 に答える 2

3

簡単な方法の 1 つは、フォームセットをインスタンス化した後に行うことです。

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)
于 2013-11-08T21:16:09.377 に答える
1

それほど複雑にする必要はありません。フォームの初期化に kwarg 'person' を追加するだけです。この新しいフォームを PeaForm と呼んでいます。これは、PeaForm としてリストしたものが実際には Formset 型であるためです。

class PeaForm(ModelForm):

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

        person = kwargs.pop('person')
        super(PeaForm, self).__init__(*args, **kwargs)
        qs = Bowl.objects.filter(user=person)
        self.fields['bowl'].queryset = qs


    class Meta():
        model = Pea

ファクトリで使用しているため、フォームを作成するときにメソッドをカリー化する必要があります。

from django.utils.functional import curry

person = request.user
PeaFormset = inlineformset_factory(django.contrib.auth.models.User, Pea, form=PeaForm)
PeaFormSet.form = staticmethod(curry(PeaForm, person=person))

これで、ユーザーに属するボウルのみが PeaForm の QS に含まれます。

于 2013-11-08T23:38:56.303 に答える