2016-04-22 5 views
0

ich einen Auftrag Modell haben:Django: Limit models.ForeignKey Ergebnisse

class Order(models.Model): 
    profile = models.ForeignKey(Profile, null=True, blank=True) 

, die alle möglichen Profile für einen Auftrag gibt, die nicht notwendig ist und das Laden der Admin-Seite, um zu verlangsamen.

Ich möchte das Profil zurückgeben einfach das Profil des Benutzers, der die Bestellung aufgegeben hat. Ich habe versucht, zu ändern, es zu:

class Order(models.Model): 
    profile = models.ForeignKey(Profile, null=True, blank=True, limit_choices_to={'order': 99999}) 

die für eine Auftragsnummer 99999 das richtige Profil zurückgibt, aber wie kann ich diese dynamisch erhalten. Dem Auftragsmodell ist das "Selbst" nicht bekannt, aber die Auftragsnummer ist in der URL enthalten.

Was ist der beste Weg, dies zu tun?

+1

Wenn das Profil fest ist, klingt es so, als ob es überhaupt nicht editierbar sein sollte. Sie könnten es zu einem [Nur-Lese-Feld] (https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields) machen und den Wert [bei der Bestellung festlegen wird platziert] (https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model). – Alasdair

+0

Verwenden Sie den django admin? –

+0

Ja, das ist mit der Django Admin-Site – James

Antwort

0

Wenn Sie die Django Admin verwenden, können Sie die Methode formfield_for_foreignkey auf ModelAdmin Klasse überschreiben die queryset für das Profilfeld dinamically auf einem GET-Parameter zum Beispiel auf Basis zu ändern (wie Sie den Zugriff auf request innerhalb der Methode haben.

Schauen Sie sich das Beispiel aus der Dokumentation (für Ihren Fall angepasst):

class MyModelAdmin(admin.ModelAdmin): 
    def formfield_for_foreignkey(self, db_field, request, **kwargs): 
     if db_field.name == "profile": 
      # You can get the order number from the GET parameter: 
      # order = request.GET.get('order') 
      # or a fixed number: 
      order = '12345' 
      kwargs["queryset"] = Profile.objects.filter(order=order) 
     return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) 

Referenz in der Dokumentation: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey

+0

Hmm, ich habe versucht, den obigen Code zu meiner OrderAdmin-Klasse hinzufügen, aber dies führt nur zu einem 504 Gateway Time-Out ... – James

+0

Obwohl es Art arbeitet mit der Reihenfolge = '12345' Linie , wenn auch mit dem falschen Profil angefügt – James

+0

Können Sie das Debug deaktivieren, um zu sehen, welche Ausnahme geworfen wird, die die 504 verursacht? –

0

nahm ich anot Ihr Blick darauf und es scheint zu funktionieren, obwohl es wie ein bisschen hack scheint! Das Problem war, dass die Bestellnummer in der Anfrage nicht vorhanden zu sein scheint, daher analysiere ich die angeforderte URL. Ich habe dies in meinem Auftrag Leiter:

def formfield_for_foreignkey(self, db_field, request, **kwargs): 
    if db_field.name == "profile": 
     try: 
      order = int(filter(str.isdigit, str(request.path_info))) 
     except: 
      order = request.GET.get('order') 
     kwargs["queryset"] = Profile.objects.filter(order=order) 
    return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) 

Die Linie, die die URL-Zeichenfolge für eine ganze Zahl Filter arbeitet für den Änderungsauftrag Seite des Admin, aber nicht für die Bestellseite Übersicht arbeiten, so fügte ich die versuchen/außer. Irgendwelche Vorschläge/Verbesserungen willkommen!

0

Ich nehme an, aus dem Kontext beziehen Sie sich auf die Anzeige auf der Django Admin-Seite. Wenn Sie raw_id_fields = { ‚my_foreign_key‘} gesetzt

Sie eine Nummer, der Textbeschreibung von verwandten Modell (von str) und eine schöne Pop-up-Box erhalten eine Instanz der Admin-Seite für ähnliche Modelle zu öffnen.

Sie könnten alternativ list_select_related = True verwenden, um das gleiche Verhalten zu erhalten, das Sie jetzt haben, aber mit ein paar Größenordnungen weniger Abfragen.