Saya mengalami kesulitan mencoba memahami cara membuat bidang pilihan dinamis di django. Saya memiliki model menyiapkan sesuatu seperti:
class rider(models.Model):
user = models.ForeignKey(User)
waypoint = models.ManyToManyField(Waypoint)
class Waypoint(models.Model):
lat = models.FloatField()
lng = models.FloatField()
Apa yang saya coba lakukan adalah membuat pilihan Bidang yang nilainya adalah titik arah yang terkait dengan pengendara itu (yang akan menjadi orang yang masuk).
Saat ini saya mengganti init dalam formulir saya seperti ini:
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()])
Tapi yang dilakukan hanyalah mendaftar semua titik jalan, mereka tidak terkait dengan pengendara tertentu. Ada ide? Terima kasih.
python
django
django-forms
django-templates
apa apa
sumber
sumber
CheckboxSelectMultiple
widget dengan ini, Anda akan ingin menggunakanMultipleChoiceField
atauModelMultipleChoiceField
. Pada awalnya, tampaknya berfungsi denganChoiceField
, tetapi internal akan rusak saat Anda mencoba menyimpan formulir.CheckboxSelectMultiple
widget dengan kode ini. Pastikan untuk mengubahChoiceForm
keMultipleChoiceForm
Ada solusi bawaan untuk masalah Anda: ModelChoiceField .
Secara umum, itu selalu layak untuk dicoba digunakan
ModelForm
saat Anda perlu membuat / mengubah objek database. Berfungsi di 95% kasus dan ini jauh lebih bersih daripada membuat implementasi Anda sendiri.sumber
masalahnya adalah saat Anda melakukannya
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)])
dalam permintaan pembaruan, nilai sebelumnya akan hilang!
sumber
Bagaimana jika meneruskan contoh pengendara ke formulir saat memulainya?
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)
sumber
Di bawah solusi kerja dengan bidang pilihan normal. masalah saya adalah bahwa setiap pengguna memiliki opsi kolom pilihan KUSTOM mereka sendiri berdasarkan beberapa kondisi.
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
sumber
Seperti yang ditunjukkan oleh Breedly dan Liang, solusi Ashok akan mencegah Anda mendapatkan nilai pilihan saat memposting formulir.
Satu cara yang sedikit berbeda, tetapi masih belum sempurna, untuk mengatasinya adalah:
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)
Ini dapat menyebabkan beberapa masalah konkurensi.
sumber
Anda dapat mendeklarasikan bidang tersebut sebagai atribut kelas satu dari formulir Anda dan cukup menyetel pilihan secara dinamis:
class WaypointForm(forms.Form): waypoints = forms.ChoiceField(choices=[]) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) waypoint_choices = [(o.id, str(o)) for o in Waypoint.objects.filter(user=user)] self.fields['waypoints'].choices = waypoint_choices
Anda juga dapat menggunakan ModelChoiceField dan menyetel queryset di init dengan cara yang sama.
sumber
Jika Anda membutuhkan bidang pilihan dinamis di django admin; Ini bekerja untuk 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
Semoga ini membantu.
sumber