2010-11-08 8 views
11

Ich habe diese Modelle (I die Anzahl der Felder begrenzt haben nur diejenigen erforderlich)In Django, wie man die Auswahl eines Foreignfield basierend auf einem anderen Feld im selben Modell begrenzt?

class unit(models.Model): 
    name = models.CharField(max_length=200) 

class project(models.Model): 
    name = models.CharField(max_length=200) 

class location(address): 
    project = models.ForeignKey(project) 

class project_unit(models.Model): 
    project = models.ForeignKey(project)   
    unit = models.ForeignKey(unit) 

class location_unit(models.Model): 
    project = models.ForeignKey(project)  
     #Limit the selection of locations based on which project has been selected 
    location = models.ForeignKey(location) 
     #The same here for unit. But I have no idea how. 
    unit = models.ForeignKey(project_unit)  

Mein Neuling Kopf kann einfach nicht begreifen, wie die beiden Felder, Standort und Gerät, in dem location_unit Modell zu begrenzen, um nur die Auswahl, die sich auf das ausgewählte Projekt in location_unit bezieht. Sollte ich das Modellformular überschreiben und dort eine Abfrage machen oder kann ich limit_choices_to verwenden. Wie auch immer, ich habe es versäumt beide

Edit: Nur um zu verdeutlichen, möchte ich dies in der Django Admin passieren. Ich habe auch formfield_for_foreignkey ausprobiert, aber immer noch ein Nein für mich.

EDIT 2:

def formfield_for_foreignkey(self, db_field, request, **kwargs): 
    if db_field.name == "unit": 
     kwargs["queryset"] = project_unit.objects.filter(project=1) 
     return db_field.formfield(**kwargs) 
    return super(location_unit_admin, self).formfield_for_foreignkey(db_field, request, **kwargs) 

Der obige Codeausschnitt funktioniert. Aber ich möchte natürlich nicht, dass das Projekt auf 1 zeigt. Wie referenziere ich die Modelle project_id? Ich versuchte dies:

kwargs["queryset"] = project_unit.objects.filter(project=self.model.project.project_id) 

Aber das funktioniert nicht (eigentlich habe ich versucht bin eine Menge von Variationen, ja ich ein django Neuling)

Antwort

3

Ihre formfield_for_foreignkey sieht aus wie es eine gute Richtung sein könnte, aber Sie müssen feststellen, dass ModelAdmin (self) Ihnen keine bestimmte Instanz gibt. Sie werden feststellen, dass aus den request abzuleiten haben (möglicherweise eine Kombination aus django.core.urlresolvers.resolve und request.path)


Wenn Sie nur diese Funktionalität im Admin wollen (und nicht die Validierung im allgemeinen Modell), können Sie ein benutzerdefiniertes Formular verwenden mit dem Modell Admin-Klasse:

forms.py:

from django import forms 

from models import location_unit, location, project_unit 

class LocationUnitForm(forms.ModelForm): 
    class Meta: 
     model = location_unit 

    def __init__(self, *args, **kwargs): 
     inst = kwargs.get('instance') 
     super(LocationUnitForm, self).__init__(*args, **kwargs) 
     if inst: 
      self.fields['location'].queryset = location.objects.filter(project=inst.project) 
      self.fields['unit'].queryset = project_unit.objects.filter(project=inst.project) 

admin.py:

from django.contrib import admin 

from models import location_unit 
from forms import LocationUnitForm 

class LocationUnitAdmin(admin.ModelAdmin): 
    form = LocationUnitForm 

admin.site.register(location_unit, LocationUnitAdmin) 

(schrieben gerade diese im laufenden Betrieb ohne Prüfung, so dass keine Garantie, dass sie wird funktionieren, aber es sollte in der Nähe sein.)

+0

Hallo Eternicode, Danke, dass du dir Zeit für mein Problem genommen hast. Aber ich habe eine Frage, ist dieser Code von dir dynamisch, weil es mir scheint, dass, wenn ich eine location_unit erstellen möchte, der __init__ bereits ausgeführt wurde und nicht erneut ausgeführt wird, egal welches Projekt ich auswähle. Also muss ich zuerst ein Projekt auswählen, dann speichern und dann die location_unit erneut eingeben, um das __init__ erneut auszuführen und dann zeigen die Einheiten nur diejenigen an, die zu diesem Projekt gehören. Habe ich das richtig verstanden? – Brian

+0

Vielleicht kann so etwas verwendet werden: http://stackoverflow.com/questions/3750097/how-to-read-write-input-fields-in-django-admin-tabular-inlines-use-ajax aber ich habe keine Idee, wie man das im Admin implementiert – Brian

+3

Okay, das tut genau das, was ich will :) https://github.com/digi604/django-smart-selects – Brian

Verwandte Themen