2017-01-06 8 views
0

Es gibt Spiele-Entity, jeder von ihnen könnte 1 oder mehr Plattformen haben. Außerdem könnte jedes Spiel 1 oder mehr Links zu verwandten Spielen (mit ihren eigenen Plattformen) haben. Hier sieht es aus wie in models.py:Anpassen verwandter Objekte für viele-zu-viele-Feld in Django

class Game(TimeStampedModel): 
    gid = models.CharField(max_length=38, blank=True, null=True) 
    name = models.CharField(max_length=512) 
    platforms = models.ManyToManyField(
     Platform, blank=True, null=True) 
    ... 
    #here is the self-referencing m2m field 
    related_games = models.ManyToManyField(
     "self", related_name="related", blank=True) 

Und dieses Modells sind mit diesem Code in admin.py serviert:

@admin.register(Game) 
class GameAdmin(AdminImageMixin, reversion.VersionAdmin): 
    list_display = ("created", "name", "get_platforms"...) 
    list_filter = ("platforms", "year",) 
    #I'm interested in changing the field below 
    filter_horizontal = ("related_games",) 

    formfield_overrides = { 
     models.ManyToManyField: {"widget": CheckboxSelectMultiple}, 
    } 

    def get_platforms(self, obj): 
     return ", ".join([p.name for p in obj.platforms.all()]) 

I filter_horizontal = ("related_games verlängern müssen ",) Teil von admin.py - um eine Plattforminformation zu jedem Spiel im Widget für verwandte Spiele hinzuzufügen. Es sollte aussehen (Spielname und Plattformliste): "Virtual Fighter (PS4, PSP, PS3)".

Die Anwendung verwendet Django 1.7 und Python 2.7

Vielen Dank für Ihre Aufmerksamkeit.

Antwort

1

standardmäßig, was für jedes Element in einem filter_horizontal gezeigt wird, auf das __str__ oder __unicode__ Methode des Objekts basiert, so könnte man so etwas wie der Versuch folgend:

class Game(TimeStampedModel): 
    # field definitions 
    # ... 
    def __unicode__(self): 
     return '{0} ({1})'.format(
      self.name, 
      (', '.join(self.platforms.all()) if self.platforms.exists() 
       else 'none') 
     ) 

Dies wird jede Spielshow in der macht Liste (und überall sonst) als "Name (Plattformen)", zum Beispiel "Crash Bandicoot (PS1, PS2)" oder "Battlefield (none)", wenn es keine Plattformen hat

Alternativ, wenn Sie nicht ' Wenn Sie die __unicode__ Methode Ihres Modells ändern möchten, müssen Sieeinstellen 10, um eine benutzerdefinierte ModelForm verwenden, mit der Angabe, dass die related_games Feld sollte eine benutzerdefinierte ModelMultipleChoiceField mit einem benutzerdefinierten FilteredSelectMultiple Widget, in denen Sie die render_options Methode überschreiben müssen. Die folgenden Klassen sollten in ihren jeweiligen separaten Dateien enthalten sein, aber es würde in etwa so aussehen:

+0

Und was ist, wenn diese Funktionalität nur in Admin-Teil benötigt und nur im Zusammenhang mit horizontalen Filter Widget? Ich bin neu in diesem Projekt und nehme an, dass das Ändern von __unicode__ Teil einige Sachen brechen könnte. –

+0

Ich habe die Antwort bearbeitet, um eine Alternative anstelle von überschreiben "__unicode__", obwohl es definitiv nicht so prägnant ist – ProfSmiles

+0

Erste Variante mit __unicode__ funktioniert gut. Außer Join-Methode brauchen Strings, mit Ausnahme von Objekten. Also habe ich es so gemacht: '.join ([unicode (p) für p in self.platforms.all()]) –

Verwandte Themen