3

「Product」と「Range」の 2 つのモデルを多対多フィールドでリンクします。「Product」クラスは、私が作成したのではないアプリにあるため、変更できません (そのための modeladmin を編集できます)。「製品」の「範囲」を管理者で編集できるようにしたいのですが、インライン管理者ではなく、FilteredSelectMultiple で実行したいと考えています。

簡略化された「models.py」:

class Product(models.Model):
    name = models.CharField(max_length=64)
    #etc...
    #I can't modify this class

class Range(models.Model):
    name = models.CharField(max_length=32)
    products = models.ManyToManyField(Product, related_name='ranges')

およびadmin.py:

class ProductAdmin(admin.ModelAdmin):
    # What do I put here to get a multi-select box for ranges?
    # Preferrably with one of those 'add' buttons to popup a window
    # to add ranges.

Products を変更できれば、既存のスルー テーブルを使用して ManyToManyField を配置できます。これは正常に機能しますが、前述のようにできません (または、外部アプリへのアップグレードが非常に面倒になるため、そうしません)。

助けてくれてありがとう!(PS インライン管理フォームを使用したくない理由がここで簡単にわかることを願っています。UI が不必要に複雑になります)。

4

1 に答える 1

2

申し訳ありませんが、少し遅れているかもしれませんが、グーグルで検索している人は誰でもこの回答から恩恵を受けるかもしれません. それほど簡単ではありませんが、実行可能です。独自のフォームを作成し (必要に応じて、既存のフォームから派生させることもできます)、手動で項目を読み込んで保存する必要があります。

from django import forms
from django.contrib import admin

class ProductForm(forms.ModelForm):
    # <- your own fields declaration
    ranges = forms.ModelMultipleChoiceField(
        label='Ranges',
        queryset=Range.objects.all(),
        required=False,
        widget=admin.widgets.FilteredSelectMultiple("ranges", is_stacked=False))

    class Meta:
        model = Product


class MyProductAdmin(admin.ModelAdmin):

    def save_model(self, request, obj, form, change):
        # Save first to obtain id
        super(MyProductAdmin, self).save_model(request, obj, form, change)
        # Clean and re-add related objects
        obj.range_set.clear()
        for range in form.cleaned_data['ranges']:
             obj.range_set.add(range)

    def get_form(self, request, obj=None, **kwargs):
        if obj:
            ProductForm.base_fields['ranges'].initial = [o.pk for o in obj.range_set.all()]
        else:
            ProductForm.base_fields['ranges'].initial = []
        return ProductForm

# unregister and register again
admin.site.unregister(Product)
admin.site.register(Product, MyProductAdmin)
于 2013-11-13T12:03:02.930 に答える