Djangoで動的選択フィールドを作成する方法を理解しようとして、いくつかの問題が発生しています。私は次のようなモデルを設定しています:
class rider(models.Model):
user = models.ForeignKey(User)
waypoint = models.ManyToManyField(Waypoint)
class Waypoint(models.Model):
lat = models.FloatField()
lng = models.FloatField()
私がやろうとしているのは、フィールドを選択するフィールドを作成することです。
現在、私は私のフォームでinitを次のようにオーバーライドしています:
class waypointForm(forms.Form):
def __init__(self, *args, **kwargs):
super(joinTripForm, self).__init__(*args, **kwargs)
self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.all()])
しかし、それはすべてのウェイポイントをリストするだけで、特定のライダーに関連付けられていません。何か案は?ありがとう。
ユーザーをフォームinitに渡すことで、ウェイポイントをフィルターできます
class waypointForm(forms.Form):
def __init__(self, user, *args, **kwargs):
super(waypointForm, self).__init__(*args, **kwargs)
self.fields['waypoints'] = forms.ChoiceField(
choices=[(o.id, str(o)) for o in Waypoint.objects.filter(user=user)]
)
フォームの開始中にビューからユーザーを渡す
form = waypointForm(user)
モデル形式の場合
class waypointForm(forms.ModelForm):
def __init__(self, user, *args, **kwargs):
super(waypointForm, self).__init__(*args, **kwargs)
self.fields['waypoints'] = forms.ModelChoiceField(
queryset=Waypoint.objects.filter(user=user)
)
class Meta:
model = Waypoint
あなたの問題のための組み込みソリューションがあります: ModelChoiceField 。
一般に、データベースオブジェクトを作成/変更する必要がある場合は、ModelForm
を使用してみてください。ケースの95%で機能し、独自の実装を作成するよりもずっとクリーンです。
問題はあなたがするときです
def __init__(self, user, *args, **kwargs):
super(waypointForm, self).__init__(*args, **kwargs)
self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.filter(user=user)])
更新リクエストでは、以前の値は失われます!
初期化中にライダーインスタンスをフォームに渡すのはどうですか?
class WaypointForm(forms.Form):
def __init__(self, rider, *args, **kwargs):
super(joinTripForm, self).__init__(*args, **kwargs)
qs = rider.Waypoint_set.all()
self.fields['waypoints'] = forms.ChoiceField(choices=[(o.id, str(o)) for o in qs])
# In view:
rider = request.user
form = WaypointForm(rider)
通常の選択フィールドを持つ作業ソリューションの下。私の問題は、各ユーザーがいくつかの条件に基づいて独自のカスタム選択フィールドオプションを持っていることでした。
class SupportForm(BaseForm):
affiliated = ChoiceField(required=False, label='Fieldname', choices=[], widget=Select(attrs={'onchange': 'sysAdminCheck();'}))
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
grid_id = get_user_from_request(self.request)
for l in get_all_choices().filter(user=user_id):
admin = 'y' if l in self.core else 'n'
choice = (('%s_%s' % (l.name, admin)), ('%s' % l.name))
self.affiliated_choices.append(choice)
super(SupportForm, self).__init__(*args, **kwargs)
self.fields['affiliated'].choices = self.affiliated_choice
BreedlyとLiangが指摘したように、Ashokのソリューションは、フォームを投稿するときに選択値を取得できないようにします。
少し異なるが、まだ不完全な、それを解決する方法は次のとおりです。
class waypointForm(forms.Form):
def __init__(self, user, *args, **kwargs):
self.base_fields['waypoints'].choices = self._do_the_choicy_thing()
super(waypointForm, self).__init__(*args, **kwargs)
ただし、これによりいくつかの並行性の問題が発生する可能性があります。
Django adminに動的選択フィールドが必要な場合;これはDjango> = 2.1で機能します。
class CarAdminForm(forms.ModelForm):
class Meta:
model = Car
def __init__(self, *args, **kwargs):
super(CarForm, self).__init__(*args, **kwargs)
# Now you can make it dynamic.
choices = (
('audi', 'Audi'),
('tesla', 'Tesla')
)
self.fields.get('car_field').choices = choices
car_field = forms.ChoiceField(choices=[])
@admin.register(Car)
class CarAdmin(admin.ModelAdmin):
form = CarAdminForm
お役に立てれば。