我是Django初学者,面对这个错误“music_song.album_id可能不是NULL”,我试图解决这个错误,但遗憾的是无法解决它。我把几乎所有的代码放在这里,所以请Django专家审查代码并告诉我从哪里做错了?
Views.py
def model_form_upload(request, pk):
all_song = Song.objects.all()
print'\n-------------------------------------------------------'
if request.method == 'POST':
print request.FILES
form = SongForm(request.POST, request.FILES)
if form.is_valid():
songName = request.FILES['audio_file'] #getting song name
fs = FileSystemStorage() #allocate memory
uploaded_file_url = fs.url(songName) #getting url of uploaded file
form.save() #song saved
return render(request, 'music/model_form_upload.html', {'uploaded_file_url': uploaded_file_url,
'form': form})
else:
form = SongForm()
return render(request, 'music/model_form_upload.html', {'form': form, 'all_song': all_song})
forms.py
class SongForm(forms.ModelForm):
class Meta:
model = Song
fields = ('song_title', 'audio_file')
models.py
from django.db import models
from django.core.urlresolvers import reverse
from .validators import validate_file_extension
class Album(models.Model):
artist = models.CharField(max_length=100)
album_title = models.CharField(max_length=100)
genre = models.CharField(max_length=100)
album_logo = models.FileField()
def get_absolute_url(self):
return reverse('music:upload', kwargs={'pk': self.pk})
def __str__(self):
return self.artist
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
song_title = models.CharField(max_length=250, blank=True)
audio_file = models.FileField(validators=[validate_file_extension], max_length=500)
uploaded_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.song_title
urls.py
url(r'^(?P<pk>[0-9]+)/upload/$', views.model_form_upload, name='upload')
model_form_upload.html
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
{% if uploaded_file_url %}
<strong>Song:</strong>
<audio controls>
<source src="{{ uploaded_file_url }}" type="audio/mpeg">
</audio>
<h2>Modal Example</h2>
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
<strong>Song:</strong>
<audio controls>
<source src="{{ uploaded_file_url }}" type="audio/mpeg">
</audio>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
{% endif %}
答案 0 :(得分:0)
没有将album_id传递到您的上下文中,因此弹出此错误消息。 因此,在您的模型中添加一个专辑字段。
<强> forms.py 强>
class SongForm(forms.ModelForm):
class Meta:
model = Song
fields = ('song_title', 'audio_file', 'album')
然后在您的视图中获取相册并将album.id传递到您的上下文中。
<强> views.py 强>
def model_form_upload(request, pk):
all_song = Song.objects.all()
print'\n-------------------------------------------------------'
if request.method == 'POST':
print request.FILES
form = SongForm(request.POST, request.FILES)
if form.is_valid():
album = request.POST['album'] #getting the album object
songName = request.FILES['audio_file'] #getting song name
fs = FileSystemStorage() #allocate memory
uploaded_file_url = fs.url(songName) #getting url of uploaded file
form.save() #song saved
return render(request, 'music/model_form_upload.html', {'uploaded_file_url': uploaded_file_url, 'form': form, 'id': album.id})
else:
form = SongForm()
return render(request, 'music/model_form_upload.html', {'form': form, 'all_song': all_song})
希望有所帮助
答案 1 :(得分:0)
这只是因为您尝试创建没有Album
实例的歌曲,根据您的模型结构album = your models.ForeignKey(Album, on_delete=models.CASCADE)
,您设置了专辑字段non-null
,因此{{1不能保持为空或空。
您可以将该字段设置为可空,而不是ForeignKey
,只需将models.CASCADE
加信号models.SET_NULL
添加到相册即可删除所有相关歌曲。
/pre_delete/post_delete
或者您可以在歌曲中使用字段 class Album(models.Model):
artist = models.CharField(max_length=100)
''' codes '''
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.SET_NULL,
null=True,blank=True)
@receiver(pre_delete, sender=Album)
def delete_songs_with_album(sender, instance, *args, **kwargs):
instance.song_set.all().delete()
,而不是通过删除该字段来稍微更改模型结构,并在album = models.ForeignKey(Album, on_delete=models.CASCADE)
中添加新字段ManyToManyField
1}}
Song
在后一种情况下,您仍然可以使用相册删除所有歌曲