问题
I have a Django project in which the page that should load to show the album that has just been added, does not. It should go to the primary key for that album (auto generated) with the reference: http://127.0.0.1:8000/music/1/ but instead gives the error:
Reverse for 'create_song' not found. 'create_song' is not a valid view function or pattern name.
A variant of the same problem, I assume, Is that when I click on the VIEW DETAILS BUTTON (shown below in the index.html) it doesn't load:
<div class="caption">
<h2>{{ album.album_title }}</h2>
<h4>{{ album.artist }}</h4>
<!-- View Details -->
<a href="{% url 'music:detail' album.id %}" class="btn btn-primary btn-sm" role="button">View Details</a>
<!-- Delete Album -->
<form action="#" method="post" style="display: inline;">
{% csrf_token %}
<input type="hidden" name="album_id" value="{{ album.id }}" />
<button type="submit" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form>
The code for the various sections is below:
music/templates/music/album_form.html
<div class="row">
<div class="col-sm-12 col-md-7">
<div class="panel panel-default">
<div class="panel-body">
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'music/form_template.html' %} <!-- how form fields and inputs are laid out-->
<div class="form-group>
<div class="col-sum-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
music/views.py
from django.views import generic
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .models import Album
#=============HOME PAGE===================
class IndexView(generic.ListView):
#specify template being used
template_name='music/index.html' #when we get a list of all albums, plug them into this template
context_object_name='all_albums' #if you don't use this variable it is automatically just object_list (which is used in index.html)
#make a query set
def get_queryset(self):
return Album.objects.all()
#=============DETAILS VIEW=============== details about one object
class DetailView(generic.DetailView):
#what model are we looking at /for
model=Album
template_name='music/detail.html'
#===============For the add album form
class AlbumCreate(CreateView):
model=Album
fields=['artist','album_title','genre','album_logo']
music/urls.py
from django.contrib import admin
from django.urls import include, path
from . import views #the dot means look at the current directory - look for a module called views
app_name='music'
urlpatterns = [
#this is matching /music/
path('', views.IndexView.as_view(), name='index'),
#when you use a detail view it expects a primary key
path("<pk>/", views.DetailView.as_view(), name="detail"),
#/music/album/add - dont need to specify pk
path('album/add/', views.AlbumCreate.as_view(), name="album-add"),
]
music/models.py
from django.db import models
from django.urls import reverse
# Create your models here.
class Album(models.Model):
artist=models.CharField(max_length=250)
album_title=models.CharField(max_length=500)
genre=models.CharField(max_length=100)
album_logo=models.CharField(max_length=1000)
def __str__(self):
return self.album_title+""+self.artist
def get_absolute_url(self):
return reverse('music:detail',kwargs={'pk':self.pk})
#music detail takes the primary key ..
class Song(models.Model):
album=models.ForeignKey(Album, on_delete=models.CASCADE)
file_type=models.CharField(max_length=10)
song_title=models.CharField(max_length=250)
is_favorite = models.BooleanField(default=False)
def __str__(self):
return self.song_title
Update: also including details.py
{% extends 'music/base.html' %}
{% block title %}{{ album }}{% endblock %}
{% block albums_active %}active{% endblock %}
{% block body %}
<div class="container-fluid songs-container">
<div class="row">
<!-- Left Album Info -->
<div class="col-sm-4 col-md-3">
<div class="panel panel-default">
<div class="panel-body">
<a href="{% url 'music:detail' album.id %}">
{% if album.album_logo %}
<img src="{{ album.album_logo.url }}" class="img-responsive">
{% else %}
<h3>No image to display</h3>
{% endif %}
</a>
<h1>{{ album.album_title }} <small>{{ album.genre }}</small></h1>
<h2>{{ album.artist }}</h2>
</div>
</div>
</div>
<!-- Right Song Info -->
<div class="col-sm-8 col-md-9">
<ul class="nav nav-pills" style="margin-bottom: 10px;">
<li role="presentation" class="active"><a href="{% url 'music:detail' album.id %}">View All</a></li>
<li role="presentation"><a href="{% url 'music:create_song' album.id %}">Add New Song</a></li>
</ul>
<div class="panel panel-default">
<div class="panel-body">
<h3>All Songs</h3>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Audio File</th>
<th>Favorite</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for song in album.song_set.all %}
<tr>
<td>{{ song.song_title }}</td>
<td>
<a target="_blank" href="{{ song.audio_file.url }}">
<button type="button" class="btn btn-success btn-xs">
<span class="glyphicon glyphicon-play"></span> Play
</button>
</a>
</td>
<td>
<a href="{% url 'music:favorite' song.id %}" class="btn-favorite"><span class="glyphicon glyphicon-star {% if song.is_favorite %}active{% endif %}"></span></a>
</td>
<td>
<form action="{% url 'music:delete_song' album.id song.id %}" method="post" style="display: inline;">
{% csrf_token %}
<input type="hidden" name="song_id" value="{{ song.id }}" />
<button type="submit" class="btn btn-danger btn-xs">
<span class="glyphicon glyphicon-remove"></span> Delete
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
来源:https://stackoverflow.com/questions/48007916/reverse-for-create-song-not-found-create-song-is-not-a-valid-view-function