Ich habe einige Probleme beim Versuch zu verstehen, wie ein dynamisches Auswahlfeld in Django erstellt wird. Ich habe ein Modell eingerichtet wie:
class rider(models.Model):
user = models.ForeignKey(User)
waypoint = models.ManyToManyField(Waypoint)
class Waypoint(models.Model):
lat = models.FloatField()
lng = models.FloatField()
Was ich versuche, ist eine Auswahl zu erstellen. Feld, dessen Werte die Wegpunkte sind, die mit diesem Fahrer verbunden sind (das wäre die Person, die angemeldet ist).
Momentan überschreibe ich init in meinen Formularen wie folgt:
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()])
Sie müssen jedoch nur alle Wegpunkte auflisten, da sie keinem bestimmten Fahrer zugeordnet sind. Irgendwelche Ideen? Vielen Dank.
sie können die Wegpunkte filtern, indem Sie den Benutzer an das Formular init übergeben
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)]
)
aus Ihrer Sicht beim Einleiten des Formulars übergeben Sie den Benutzer
form = waypointForm(user)
im Falle einer Musterform
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
Für Ihr Problem gibt es eine integrierte Lösung: ModelChoiceField .
Im Allgemeinen lohnt es sich immer, ModelForm
zu verwenden, wenn Sie Datenbankobjekte erstellen/ändern müssen. Funktioniert in 95% der Fälle und ist viel sauberer als das Erstellen einer eigenen Implementierung.
das Problem ist, wenn Sie es tun
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)])
bei einer Update-Anfrage geht der vorherige Wert verloren!
Wie wäre es, wenn Sie die Reiterinstanz beim Initialisieren an das Formular übergeben würden?
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)
Unter Arbeitslösung mit normalem Wahlfeld. Mein Problem war, dass jeder Benutzer seine eigenen CUSTOM-Auswahlfeldoptionen hat, die auf wenigen Bedingungen basieren.
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
Wie von Breedly und Liang angedeutet, verhindert Ashoks Lösung, dass Sie beim Posten des Formulars den ausgewählten Wert erhalten.
Ein etwas anderer, aber immer noch unvollkommener Lösungsweg wäre:
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)
Dies kann jedoch zu Problemen mit der Übereinstimmung führen.
Wenn Sie ein dynamisches Auswahlfeld in Django admin benötigen, funktioniert dies für 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
Hoffe das hilft.