4

モデルに「必須」のフィールド (スラッグ) がありますが、ModelAdmin クラスのフィールドをオプションに変更したいと考えています。ユーザーが入力しない場合は、別のフィールド (名前) によって自動的に入力されます。

class SomeModel(model.Model):
  name = model.CharField(max_length=255)
  slug = model.SlugField(unique=True, max_length=255)

ModelAdmin 内で get_form() をオーバーライドしたり、ModelForm クラスを使用してフォームを具体的に指定したりするなど、さまざまな方法でこれを実行しようとしました。

class SomeModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(self.__class__, self).get_form(request, obj, **kwargs)
        form.slug.required = False
        return form

ただし、どちらのソリューションもうまくいきませんでした。フォームを手動で作成する以外に、もっと迅速な解決策はありますか?

私はこれらのフォームをたくさん持っていますが、手作業で行うのは面倒で維持するのが難しいかもしれません.

4

3 に答える 3

5

同じ問題に自分で取り組んでいるときに、Googleでこのページを見つけました。以下もで動作しますModelAdmin

def get_form(self, *args, **kwargs):
    form = super(SomeModelAdmin, self).get_form(*args, **kwargs)
    form.base_fields['slug'].required = False
    return form

更新されたフォームから作成された後続のフォームModelFormMetaclassには、slugフィールドが不要になります。

これは、フィールドを不要にする必要があるクラスが1つだけで、保存時にデータ変換を行う必要がない状況で、より適切に機能します。クラスがたくさんある場合、またはデータ変換が必要な場合は、GoogleDroidのソリューションの方が適しています。

于 2012-07-06T16:11:40.657 に答える
1

あなたのget_form方法では、form.fields['slug'].requiredうまくいくはずです。

ただし、これを行う適切な方法は、カスタム ModelForm を提供することです。

class SomeModelForm(forms.ModelForm):
    slug = forms.CharField(required=False)

class SomeModelAdmin(admin.ModelAdmin):
    form = SomeModelForm

なお、しないでくださいsuper(self.__class__, self)。を使用するときは、常に現在のクラスに明示的に名前を付ける必要がありますsuper。そうしないと、あなたのものから継承し、次に呼び出すサブクラスsuperが壊れます。

form.fieldsではなく、編集forms.fieldsします。

と言うとself.__class__、Python が継承を実行するのを明示的に停止しています。これは、常に具象クラス (継承ツリーの下部) を参照しているためです。しかし、あなたのメソッドがそのツリーの真ん中にある場合、具体的なクラスを参照するのsuperは間違っています.1つ下からではなく、現在の場所から次のレベルを呼び出したいからです。そのため、常に自分が所属しているクラスに名前を付ける必要があります。この場合はsuper(SomeModelAdmin, self).

于 2011-05-21T18:29:02.740 に答える
1

他の人がこれが役立つと思うかもしれない場合に備えて、私はただ報告したかった.

私は決してそれをget_form行うことができず、form.fields['slug'].requiredその理由を理解することもできませんでした. ただし、ModelForm から継承した新しいフォームを作成することで問題を解決しました。

親コンストラクターを呼び出した後にinit () をオーバーライドして設定し、必要に応じて slug フィールドの内容を変更するためにオーバーライドする必要がありました。self.fields['slug'].required = Falseclean_slug()self.data['slug']

これが誰かを助けることを願っています

于 2011-05-26T01:31:16.900 に答える