Using fields from a though admin.TabularInline

Hi there.

I’m trying to develop a backoffice for my project. Probably you could help me regarding a point:

  • I’m trying to print informations relative ManyToMany field Model

Here my models.py:
from django.db import models
from django.conf import settings

TYPE_CHOIX = [
    ('0', 'Film'),
    ('1', 'Serie'),
]
class Media(models.Model):
    nom = models.CharField(max_length=255)
    mediatype = models.CharField(choices=TYPE_CHOIX, max_length=2)
    annee = models.CharField(max_length=4)
    date_ajout = models.DateTimeField(auto_now_add=True)

    def __str__(self):
    	return "{0} ({1})".format(self.nom, self.annee)

    class Meta:
        verbose_name = "media"
        ordering = ['nom']


class Film(Media):
    imdb_id = models.CharField(max_length=12)
    nom_original = models.CharField(max_length=255, null=True)
    realisateur = models.ManyToManyField('Personne', related_name='film')
    date_sortie = models.DateField(null=True)
    original_line = models.CharField(max_length=1000, null=True)

    def __str__(self):
        return "{0} ({1})".format(self.nom, self.annee)

    class Meta:
        verbose_name = "film"
        ordering = ['nom']

class Serie(Media):
    imdb_id = models.CharField(max_length=12)
    nom_original = models.CharField(max_length=255, null=True)
    showrunner = models.ManyToManyField('Personne', related_name='serie')
    date_sortie = models.DateField(null=True)
    saison = models.PositiveSmallIntegerField()
    episodes_imdb_id = models.TextField(null=True)
    original_line = models.CharField(max_length=1000, null=True)

    def __str__(self):
        return "{0}, season {1} ({2})".format(self.nom, self.saison, self.annee)

    class Meta:
        verbose_name = "serie"
        ordering = ['nom']

class Personne(models.Model):
    imdb_id = models.CharField(max_length=12, null=True)
    nom_complet = models.CharField(max_length=255)
    prenom = models.CharField(max_length=255, null=True)
    nom = models.CharField(max_length=255, null=True)
    date_ajout = models.DateTimeField(auto_now_add=True)

    def __str__(self):
    	return "{0}".format(self.nom_complet)

    class Meta:
    verbose_name = "personne"
    ordering = ['nom_complet']

So, Film or a Serie object (heritated from Media object) could have one ore more attached Personne objects (field realisateur or showrunner).

Here’s my admin.py:
from django.contrib import admin
from django import forms
from .models import Film, Serie, Note, Personne, Pays, Genre

class SerieInline(admin.TabularInline):
    model = Personne.serie.through
    fields = ('serie',)
    extra = 0

class FilmInline(admin.TabularInline):
    model = Personne.film.through
    fields = ['film',]
    readonly_fields = ('film',)
    extra = 0

class PersonneAdmin(admin.ModelAdmin):
   list_display   = ('nom_complet',)
   ordering       = ('nom_complet', )
   search_fields  = ('nom_complet',)
   inlines        = [FilmInline, SerieInline]
admin.site.register(Personne, PersonneAdmin)

What I would like to do:

The view when I edit a Personne object is OK

  • it prints Personne object information
  • it prints below Film or Serie related

However, the FilmAdmin method just returns a field called film, which is just the str of the related model. I would like to prints other fields related, like Film.nom_original, or Serie.date_sortie, and trick them (append to them an URL, for example).

How could I do such a thing? Did I miss something in my SerieInline or FilmInline method? Probably the model option on it is not good?

Thanks a lot for your returns!
Chers!

N.

And the solution is using instance.THROUGHFIELD_NAME.FIELD_NAME :slight_smile:
Next step: trying to sort the Personne.films_realisateur.through request.

class RealisateurFilmInline(admin.TabularInline):
     model = Personne.films_realisateur.through
     fields = ['nom', 'nom_original', 'annee', 'date_sortie',]
     readonly_fields = ('film', 'nom', 'nom_original', 'annee', 'date_sortie',)
     extra = 0
     verbose_name = "realisateur_film"
     verbose_name_plural = "realisateur_film"
     can_delete = False

 def nom(self, instance):
     return instance.film.nom

 def annee(self, instance):
     return instance.film.annee

 def nom_original(self, instance):
     return instance.film.nom_original

 def date_sortie(self, instance):
     return instance.film.date_sortie
     
 nom.short_description = 'nom'
 annee.short_description = 'annee'
 nom_original.short_description = 'nom_original'
 date_sortie.short_description = 'date_sortie'

Cheers!

N.