2011-01-03 15 views
1

Ich bin mir nicht ganz sicher, wie ich die Frage formulieren soll, die ich stellen möchte. Angenommen, Sie haben zwei Profilobjekte, die möglicherweise einem Benutzer zugeordnet werden können. Nur einer von ihnen wird assoziieren (es gibt eine Eins-zu-Eins-Zuordnung), aber es könnte eines von zwei möglichen Profilobjekten sein. Mein Admin-Code sieht so aus:Django - Unterklasse UserAdmin zum Erstellen dynamischer Vorlagen?

admin.site.unregister(User) 

class AProfileInline(admin.StackedInline): 
    model = UserProfileA 

class BProfileInline(admin.StackedInline): 
    model = UserProfileB 

class UserProfileAdmin(UserAdmin): 
    inlines = [AProfileInline, BProfileInline, ] 

admin.site.register(User, UserProfileAdmin) 

Das funktioniert zwar, aber es zeigt natürlich unnötige Informationen an. Es wäre schön, wenn die Admin-Seite nur das richtige inline anzeigen würde. Ich denke, das ist kompliziert und wahrscheinlich ein Problem, wenn ich zum Beispiel von einem Profiltyp zum anderen wechseln möchte. Irgendwelche Gedanken?

+1

Also, wie würden Sie mit einem neuen Benutzer umgehen? Erstellt etwas external automatisch ein Standardprofil des einen oder anderen Typs? Wie würden Sie das Profil eines Benutzers von einem Typ zum anderen ändern? –

Antwort

0

Dies ist eine Möglichkeit, es zu tun. Denken Sie daran, Dies ist ein Hack. Ich habe diesen Code von ModelAdmin Code in django.contrib.admin.options basiert.

admin.site.unregister(User) 

class AProfileInline(admin.StackedInline): 
    model = UserProfileA 

class BProfileInline(admin.StackedInline): 
    model = UserProfileB 

class UserProfileAdmin(UserAdmin): 
    inlines = [AProfileInline, BProfileInline, ] 

    def get_object(self, *args, **kwargs): 
     obj = super(UserProfileAdmin, self).get_object(*args, **kwargs) 
     if obj: 
      self.inline_instances = [] 
      if AProfileInline.model.objects.filter(user=obj): 
       inline_instance = AProfileInline(self.model, self.admin_site) 
       self.inline_instances.append(inline_instance) 
      if BProfileInline.model.objects.filter(user=obj): 
       inline_instance = BProfileInline(self.model, self.admin_site) 
       self.inline_instances.append(inline_instance) 
     return obj 

admin.site.register(User, UserProfileAdmin) 

Diese Lösung setzt voraus, dass beide UserProfileA und UserProfileB haben Fremdschlüsselbeziehungen zu User durch ein Feld user genannt.

Die Funktionen change_view und delete_view rufen get_object auf, daher sollte dieser Code die Inline-Formularinstanzen ordnungsgemäß ersetzen, bevor diese Ansichten gerendert werden.

Dieser Code überschreibt get_object die folgenden zusätzlichen Aktionen ausführen:

  1. Die Inline-Formulare standardmäßig leer sind (für bereits bestehende Objekte)
  2. Wenn ein UserProfileA gefunden wird, dass die aktuelle User verweist (durch das Feld user), wird ein Inline-Formular für UserProfileA hinzugefügt.
  3. Wenn eine UserProfileB gefunden wird, die auf das aktuelle User verweist (über das Feld user), wird ein Inline-Formular für UserProfileB hinzugefügt.

Quirks dieser Lösung:

  • UserProfileAdmin.__init__ wird immer noch eine Standardversion von self.inline_instances erstellen, die dann überschrieben werden, wenn change_view oder delete_view verwendet werden.
  • Diese Funktion war nie dazu gedacht, das zu tun, wofür der obige Code sie verwendet. Wenn in einem anderen Code UserProfileAdmin.get_object aufgerufen wird, werden die Inline-Formulare unnötig neu berechnet.
+0

Sie müssen nicht sagen 'if AProfileInline.model.objects.filter (user = obj) .count(): '; Sie könnten einfach sagen, wenn AProfileInline.model.objects.filter (user = obj): '. –

+0

Danke für den Tipp. Habe es einfach geändert. –

+0

Ich gebe das eine Chance, danke für den Tipp! – JPC