16

CharFieldを持つモデルがあり、管理者でウィジェットに選択肢を追加したいと思います。この理由は、私がプロキシモデルを使用していて、このCharFieldを共有するモデルがたくさんあるが、それぞれに異なる選択肢があるためです。

class MyModel(MyBaseModel):
    stuff = models.CharField('Stuff', max_length=255, default=None)

    class Meta:
        proxy = True

class MyModelAdmin(admin.ModelAdmin):
    fields = ('stuff',)
    list_display = ('stuff',)
admin.site.register(MyModel, MyModelAdmin)

このモデルでは、で使用MY_CHOICESしたいと思いますMyModelAdmin

ウィジェットをオーバーライドしますか?フォーム全体を上書きする必要がありますか?

4

7 に答える 7

24
from django.contrib import admin
from django import forms

class MyModel(MyBaseModel):
    stuff = models.CharField('Stuff', max_length=255, default=None)

    class Meta:
        proxy = True

class MyModelForm(forms.ModelForm):
    MY_CHOICES = (
        ('A', 'Choice A'),
        ('B', 'Choice B'),
    )

    stuff = forms.ChoiceField(choices=MY_CHOICES)

class MyModelAdmin(admin.ModelAdmin):
    fields = ('stuff',)
    list_display = ('stuff',)
    form = MyModelForm

admin.site.register(MyModel, MyModelAdmin)

参照:https ://docs.djangoproject.com/en/dev/ref/forms/fields/#choicefield

于 2012-09-27T16:54:42.560 に答える
5

ModelAdmin使用するフォームを上書きする必要があります。

class MyForm(forms.ModelForm):
    stuff = forms.CharField('Stuff', max_length=255, choices=MY_CHOICES, default=None)

    class Meta:
        model = MyModel
        fields = ('stuff', 'other_field', 'another_field')


class MyModelAdmin(admin.ModelAdmin):
    fields = ('stuff',)
    list_display = ('stuff',)
    form = MyForm

動的な選択が必要な場合は、次のようなことを行うことができます。

class MyForm(forms.ModelForm):
    stuff = forms.CharField('Stuff', max_length=255, choices=MY_CHOICES, default=None)

    def __init__(self, stuff_choices=(), *args, **kwargs):
        # receive a tupple/list for custom choices
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['stuff'].choices = stuff_choices

そして、あなたので何ModelAdminが起こるかを__init__定義しMY_CHOICES、代わりにそこにフォームインスタンスを割り当てます:

幸運を!:)

于 2012-09-27T16:56:46.210 に答える
5

formfield_for_choice_field()新しいフォームを作成する必要がない方法でオーバーライドできます。

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_choice_field(self, db_field, request, **kwargs):
        if db_field.name == 'status':
            kwargs['choices'] = (
                ('accepted', 'Accepted'),
                ('denied', 'Denied'),
            )
            if request.user.is_superuser:
                kwargs['choices'] += (('ready', 'Ready for deployment'),)
        return super().formfield_for_choice_field(db_field, request, **kwargs)

formfield_for_choice_fieldを参照してください

于 2018-03-29T14:06:07.420 に答える
5

カスタムフォームは必要ありません。

これはあなたが必要とする最小限です:

# models.py
from __future__ import unicode_literals

from django.db import models

class Photo(models.Model):
    CHOICES = (
        ('hero', 'Hero'),
        ('story', 'Our Story'),
    )

    name = models.CharField(max_length=250, null=False, choices=CHOICES)

# admin.py
from django.contrib import admin
from .models import Photo


class PhotoAdmin(admin.ModelAdmin):
    list_display = ('name',)


admin.site.register(Photo, PhotoAdmin)
于 2018-12-29T21:08:05.363 に答える
0

ジェラールの答えでは、あなたが保つならば:

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

次に、adminから新しいモデルを追加しようとすると、常に「このフィールドは必須です」というメッセージが表示されます。すべての必須フィールド。

初期化から削除する必要がありstuff_choices=()ます:

def __init__(self,*args, **kwargs):
于 2014-01-21T09:20:36.193 に答える
0

データベースレベルでデータをどのように保存するかを考える必要があります。私はこれを行うことをお勧めします:

  1. このpipコマンドを実行します。pip install django-multiselectfield
  2. あなたのmodels.pyファイル:

    from multiselectfield import MultiSelectField
    
    MY_CHOICES = (('item_key1', 'Item title 1.1'),
              ('item_key2', 'Item title 1.2'),
              ('item_key3', 'Item title 1.3'),
              ('item_key4', 'Item title 1.4'),
              ('item_key5', 'Item title 1.5'))
    
    class MyModel(models.Model):
          my_field = MultiSelectField(choices=MY_CHOICES)
    
  3. あなたのsettings.pyで:

     INSTALLED_APPS = (
          'django.contrib.auth',
          'django.contrib.contenttypes',
          'django.contrib.sessions',
          'django.contrib.sites',
          'django.contrib.admin',
    
          #.....................#
    
          'multiselectfield',
    )
    
  4. MAGICが起こるのを見てください!

ソース:

于 2016-12-14T16:43:11.583 に答える
0

Postgresのスペシャルですぐに機能するソリューションの下ArrayField

# models.py

class MyModel(models.Model):
    class Meta:
        app_label = 'appname'

    name = models.CharField(max_length=1000, blank=True)
  
    ROLE_1 = 'r1'
    ROLE_2 = 'r2'
    ROLE_3 = 'r3'

    ROLE_CHOICES = (
        (ROLE_1, 'role 1 name'),
        (ROLE_2, 'role 2 name'),
        (ROLE_3, 'role 3 name'),
    )

    roles = ArrayField(
        models.CharField(choices=ROLE_CHOICES, max_length=2, blank=True),
        default=list
    )

# admin.py

class MyModelForm(ModelForm):
    roles = MultipleChoiceField(choices=MyModel.ROLE_CHOICES, widget=CheckboxSelectMultiple)


@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm
    list_display = ("pk", "name", "roles")

(Django 2.2)

于 2020-07-31T14:08:02.733 に答える