问题
I am creating a demo Django website where you browse Billy Joel's albums . You click on an album to view all songs.
(If it happens to be on: http://104.131.200.120/albums/all/--there's hardly any data at the moment. Only one song in Cold Spring Harbor, none in An Innocent Man)
I can't figure out how to display the song name in the album page. It can tell if there is a song, because Cold Spring Harbor prints out an empty "name/description" line, and An Innocent Man doesn't.
Here's the view
def album(request, album_id=1):
album = Album.objects.get(id=album_id)
album_songs = AlbumSong.objects.filter(id=album_id)
print(str(album_songs))
return render_to_response("album.html",
{"album": album, "album_songs" : album_songs})
(the print results in [<AlbumSong: Cold Spring Harbor: 10: Got To Begin Again>] being written to the console, when Cold Spring Harbor is selected.)
The model (note that the Song and Album models are not linked by foreign key. There's an intermediate table, AlbumSong):
from django.db import models
from django.contrib.auth.models import User
from time import time
def get_upload_file_name(instance, filename):
return "uploaded_files/%s_%s" % (str(time()).replace(".", "_"), filename)
class Album(models.Model):
title = models.CharField(max_length=70)
pub_date = models.DateField('release date')
is_official = models.BooleanField(default=False)
is_concert = models.BooleanField(default=False)
likes = models.IntegerField(default=0)
thumbnail = models.FileField(upload_to=get_upload_file_name, blank=True, null=True)
def __str__(self):
return self.title
class Song(models.Model):
name = models.CharField(max_length=100)
sub_name = models.CharField(max_length=200, null=True, blank=True)
length_seconds = models.IntegerField()
lyrics_url = models.TextField(default="", blank=True, null=True)
def __str__(self):
return self.name
class AlbumSong(models.Model):
song_id = models.ForeignKey(Song)
album_id = models.ForeignKey(Album)
sequence_num = models.IntegerField()
class Meta:
unique_together = ('album_id', 'sequence_num',)
unique_together = ('album_id', 'song_id',)
def __str__(self):
return str(self.album_id) + ": " + str(self.sequence_num) + ": " + str(self.song_id)
class FavoriteSongs(models.Model):
user_id = models.ForeignKey(User)
song_id = models.ForeignKey(Song)
sequence_num = models.IntegerField()
class Meta:
unique_together = ('user_id', 'song_id',)
unique_together = ('user_id', 'sequence_num',)
def __str__(self):
return "user=" + str(self.user_id) + ", song=" + str(self.song_id) + ", number=" + str(self.sequence_num)
class FavoriteAlbums(models.Model):
user_id = models.ForeignKey(User)
album_id = models.ForeignKey(Album)
sequence_num = models.IntegerField()
class Meta:
unique_together = ('user_id', 'album_id',)
unique_together = ('user_id', 'sequence_num',)
def __str__(self):
return "user=" + str(self.user_id) + ", album=" + str(self.album_id) + ", number=" + str(self.sequence_num)
and template:
{% extends "base.html" %}
{% block title %}Album detail{% endblock %}
<!-- <div id="sidebar"> -->
{% block sidebar %}
<UL>
<LI><a href="/albums/all">Albums</A></LI>
</UL>
{% endblock %}
<!-- </div> -->
{% block content %}
<H1>{{ album.title }}</H1>
<P>{{ album.body }}</P>
{% if album.thumbnail %}
<P><img src="/static/{{ album.thumbnail }}" width="200"/></P>
{% endif %}
<P><UL>
<LI>Released: {{ album.pub_date }}</LI>
<LI>Official: {{ album.is_official }}</LI>
<LI>Concert: {{ album.is_concert }}</LI>
</UL></P>
<H2>Songs</H2>
{% for album_song in album_songs %} <!-- No colon after "album_songs" -->
<div>
<P><UL>
<LI>Name: <a href="/songs/get/{{ song.id }}">{{ album_song.song.name }}</a><UL>
<LI>Description: {{ album_song.song.sub_name }}</LI>
</UL></LI>
</UL></P>
</div>
{% endfor %}
<P><a href="/albums/like/{{ album.id }}">Like this album</A> -- {{ album.likes }} people liked this album.</P>
{% endblock %}
How do I display the song name in the template? What should album_song.song.name be changed to?
Thank you.
回答1:
The problem is your field names. For some reason, you've called your foreign keys from AlbumSong "song_id" and "album_id". So you should use the same names in the template: {{ album_song.song_id.name }}.
However, it doesn't make sense to use this name. The Django field does not represent an ID, it represents the actual Song object. Django already creates an underlying database field with an "_id" suffix, so in this case it's created one called "song_id_id", which is silly. Rename your fields "song" and "album", and keep your template the way it is.
来源:https://stackoverflow.com/questions/25232741/how-to-display-value-of-a-field-in-a-linked-table-in-a-django-template