1

ここで私の django ModelAdmin では、現在のユーザーのグループに基づいて外部キーの選択をフィルタリングし、追加と変更の両方の形式でそれを実現したいと考えています次のコードを使用して、追加ビューでそれを達成しました。

add_view

def add_view(self, request, form_url = '', extra_context = None):
    service_sector = common.getServiceSector(request.user)
    ModelForm = self.get_form(request)
    if request.POST:
        form = ModelForm(request.POST, request.FILES)
    else:
        form = ModelForm()
    if service_sector:
        qs = form['member'].field.queryset
        qs = qs.filter(service_sector = service_sector)
        form['member'].field.queryset = qs
    adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)),
    self.prepopulated_fields, self.get_readonly_fields(request),
    model_admin=self)
    context = {
    'adminform': adminForm,
    'is_popup': "_popup" in request.REQUEST,
    'show_delete': False,
    'root_path': self.admin_site.root_path,
    }
    context.update(extra_context or {})
    return self.render_change_form(request, context, form_url=form_url, add=True)

ここでは、正常に動作しています。このモデルには、一意のフィールドEmailがあり、それが change_view で問題を引き起こしています。以下に change_view コードを示します。

変更_ビュー

def change_view(self, request, object_id, form_url = '', extra_context = None):
    qs = self.model._default_manager.get_query_set()

    service_sector = common.getServiceSector(request.user)
    bene_object = Beneficiary.objects.get(pk=object_id)
    ModelForm = self.get_form(request, bene_object)
    if request.POST:
        form = ModelForm(request.POST, request.FILES)
    else:                     

        form = ModelForm(instance=bene_object)            
    if service_sector:
        qs = form['member'].field.queryset
        qs = qs.filter(service_sector = service_sector)
        form['member'].field.queryset = qs
    adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)),
    self.prepopulated_fields, self.get_readonly_fields(request),
    model_admin=self)
    context = {
    'adminform': adminForm,
    'is_popup': "_popup" in request.REQUEST,
    'show_delete': False,
    'root_path': self.admin_site.root_path,
    }
    context.update(extra_context or {})
    return self.render_change_form(request, context, form_url = form_url, change = True)

change_view をchange = True返しましたが、オブジェクトを新しいオブジェクトとして保存しようとしています。Email already existsメール フィールドが一意の値フィールドであるため、エラーが発生します。または、次のように通常の change_view リターンを使用することは可能ですか:

return super(ModelAdmin, self).change_view(request, form_url, extra_context)

もしそうなら、どうすれば外部キーの選択肢をフィルタリングできますか。または、render_change_formこれを達成するためにどのように使用しますか? 前もって感謝します。

4

1 に答える 1

5

私はこの問題を解決し、他の人を助けるかもしれない答えをここに投稿しました。ここでの質問は、この問題を解決するのに役立ちました。次のコードを使用して、ユーザーのグループに基づいてforeignkeyフィルターを実行しました。これは、インラインフォームセットを含むdjango adminのフォームの追加と変更の両方に対して行われます。私は以下のコードを与えています:

def render_change_form(self, request, context, *args, **kwargs):
    model = self.model
    opts = model._meta
    formsets = []

    #Change view
    if 'change' in kwargs.keys():
        object_id   = kwargs['obj'].id  #To get object id
        object      = Modelobjects.get(pk=object_id)
        ModelForm   = self.get_form(request, object)
        qs          = self.model._default_manager.get_query_set()
        if request.POST:
            form = ModelForm(request.POST, request.FILES)
        else:
            form = ModelForm(instance = object)
        service_sector = common.getServiceSector(request.user)
        if service_sector:
            #To filter foreignkey
            qs = form['member'].field.queryset
            qs = qs.filter(service_sector = service_sector)
            form['member'].field.queryset = qs
        adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)),
        self.prepopulated_fields, self.get_readonly_fields(request),
        model_admin=self)
        media = self.media + adminForm.media

        #To get inline formsets used
        prefixes = {}
        for FormSet, inline in zip(self.get_formsets(request),
                                   self.inline_instances):
            prefix = FormSet.get_default_prefix()
            prefixes[prefix] = prefixes.get(prefix, 0) + 1
            if prefixes[prefix] != 1:
                prefix = "%s-%s" % (prefix, prefixes[prefix])
            formset = FormSet(instance=object, prefix=prefix,
                              queryset=inline.queryset(request))
            formsets.append(formset)

        inline_admin_formsets = []
        for inline, formset in zip(self.inline_instances, formsets):
            fieldsets = list(inline.get_fieldsets(request))
            readonly = list(inline.get_readonly_fields(request))
            inline_admin_formset = helpers.InlineAdminFormSet(inline, formset,
                fieldsets, readonly, model_admin=self)
            inline_admin_formsets.append(inline_admin_formset)
            media = media + inline_admin_formset.media

    else:
        #Add view
        ModelForm   = self.get_form(request)
        qs          = self.model._default_manager.get_query_set()
        if request.POST:
            form = ModelForm(request.POST, request.FILES)
        else:
            form = ModelForm()
        service_sector = common.getServiceSector(request.user)
        if service_sector:
            qs = form['member'].field.queryset
            qs = qs.filter(service_sector = service_sector)
            form['member'].field.queryset = qs
        adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)),
        self.prepopulated_fields, self.get_readonly_fields(request),
        model_admin=self)
        media = self.media + adminForm.media

        prefixes = {}
        for FormSet, inline in zip(self.get_formsets(request),
                                   self.inline_instances):
            prefix = FormSet.get_default_prefix()
            prefixes[prefix] = prefixes.get(prefix, 0) + 1
            if prefixes[prefix] != 1:
                prefix = "%s-%s" % (prefix, prefixes[prefix])
            formset = FormSet(instance=self.model(), prefix=prefix,
                              queryset=inline.queryset(request))
            formsets.append(formset)

        inline_admin_formsets = []
        for inline, formset in zip(self.inline_instances, formsets):
            fieldsets = list(inline.get_fieldsets(request))
            readonly = list(inline.get_readonly_fields(request))
            inline_admin_formset = helpers.InlineAdminFormSet(inline, formset,
                fieldsets, readonly, model_admin=self)
            inline_admin_formsets.append(inline_admin_formset)
            media = media + inline_admin_formset.media

    context = {
    'adminform': adminForm,
    'title': _('Add %s') % force_unicode(opts.verbose_name),
    'is_popup': "_popup" in request.REQUEST,
    'show_delete': False,
    'media': mark_safe(media),
    'inline_admin_formsets': inline_admin_formsets,
    'root_path': self.admin_site.root_path,
    }
    return super(ModelAdmin, self).render_change_form(request, context, args, kwargs)

ここで、オブジェクト ID が取得されkwargs['obj'].id、foreignkey がフィルター処理されます。

qs = form['member'].field.queryset
qs = qs.filter(service_sector = service_sector)
form['member'].field.queryset = qs

これは、 foreignkeycommon.getServiceSectorフィルター条件に使用しているカスタム メソッドです。要件に合わせて独自の方法を定義できます。これが他の人に役立つことを願っています。ありがとう。

于 2012-06-29T05:43:22.560 に答える