[Python] How to restrict a foreign key form field based on previously selected field?

Discussão em 'Python' iniciado por Stack, Abril 15, 2025.

  1. Stack

    Stack Membro Participativo

    To preface this I know that there are some previous posts about this but the answers refer to using 3rd party packages and I was wondering if there is a solution using vanilla Django as these posts are a few years old.

    I am creating an music based app which has models for Artists, Albums and Tracks. What I'd like to do is when adding new tracks in the admin panel, if I select an Artist in the form then the Album choices are restricted to ones by that Artist but can't find anyway to make this work, at first I thought I may have been able to use "__" to make the relation, like in list_filter for the model admin but that didn't work.

    I added the artist field to the Track while trying to find a solution for this but am unsure if it is required.

    I am yet to develop most of the views for this app, this is currently just for the admin panel to add new tracks.

    class Artist(models.Model):
    name = models.CharField(max_length=100, verbose_name="Artist")
    genre = models.CharField(max_length=100)
    country = CountryField(blank_label="(select country)")
    is_approved = models.BooleanField(default=False)

    def __str__(self):
    return self.name


    class Album(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    name = models.CharField(max_length=100, verbose_name="Album")
    release_date = models.DateField()
    is_approved = models.BooleanField(default=False)

    def __str__(self):
    return self.name


    class Track(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE, verbose_name="Artist")
    album = models.ForeignKey(Album, on_delete=models.CASCADE, verbose_name="Album")
    listing_num = models.IntegerField(default=0)
    title = models.CharField(max_length=100)
    duration = models.CharField(max_length=10)
    spotify_link = models.CharField(max_length=256)
    apple_music_link = models.CharField(max_length=256)
    is_approved = models.BooleanField(default=False)

    def __str__(self):
    return self.title


    class TrackForm(ModelForm):
    class Meta:
    model = Track
    fields = [
    "artist",
    "album",
    "listing_num",
    "title",
    "duration",
    "spotify_link",
    "apple_music_link",
    ]


    Here is the code for TrackAdmin:

    class TrackAdmin(admin.ModelAdmin):
    model = Track
    list_display = [
    "artist",
    "album",
    "listing_num",
    "title",
    "duration",
    "is_approved",
    ]
    list_filter = ["album__name", "artist__name", "is_approved"]

    Continue reading...

Compartilhe esta Página