webentwicklung-frage-antwort-db.com.de

Erstellen eines dynamischen Auswahlfelds

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.

127
whatWhat

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
179
Ashok

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.

10

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!

7
Liang

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) 
4
Manoj Govindan

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
2
Deil

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.

1
Haroldo_OK

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.

0
Tobias Ernst