Django报错IntegrityError: music_song.album_id不可为NULL求排查
IntegrityError: music_song.album_id may not be NULL in Django Hey there! Let's break down why you're hitting this error and fix it right away. The core issue is simple: your Song model requires a link to an Album (since album is a ForeignKey field), but right now you're saving a song without assigning it to any album. The database enforces this mandatory link, hence the album_id may not be NULL error.
Here's the step-by-step fix:
Fetch the Album from the URL parameter
Your view already receives apkfrom the URL (this corresponds to an existing Album's ID), but you're not using it to connect the song to the album. We'll useget_object_or_404to safely grab the Album instance—it returns a 404 page if the Album doesn't exist, which is cleaner than a raw error.Link the Song to the Album before saving
When your form is valid, don't save it immediately. Usecommit=Falseto create a Song object in memory first, assign the fetched Album to it, then save it to the database.
Modified views.py code:
from django.shortcuts import render, get_object_or_404 from .forms import SongForm from .models import Song, Album from django.core.files.storage import FileSystemStorage def model_form_upload(request, pk): all_song = Song.objects.all() # Get the Album using the pk from the URL album = get_object_or_404(Album, pk=pk) print('\n-------------------------------------------------------') if request.method == 'POST': print(request.FILES) form = SongForm(request.POST, request.FILES) if form.is_valid(): songName = request.FILES['audio_file'] fs = FileSystemStorage() uploaded_file_url = fs.url(songName) # Create Song object in memory (don't save to DB yet) song = form.save(commit=False) # Assign the fetched Album to the Song's album field song.album = album # Now save the Song to the database song.save() return render(request, 'music/model_form_upload.html', { 'uploaded_file_url': uploaded_file_url, 'form': form, 'all_song': all_song # Added to keep consistency with GET requests }) else: form = SongForm() return render(request, 'music/model_form_upload.html', { 'form': form, 'all_song': all_song })
Why this works:
get_object_or_404ensures we have a valid Album that matches the URL'spk.form.save(commit=False)lets us tweak the Song object before writing it to the database—this is where we set the mandatoryalbumfield.- When we call
song.save()after assigning the album, thealbum_idfield will have a valid value, so the database won't throw the IntegrityError anymore.
Quick sanity checks:
- Verify the URL's
pkpoints to an existing Album (you can check this in the Django admin panel). - Your
SongFormdoesn't need to include thealbumfield (which is correct in your current code)—we're handling the association behind the scenes using the URL parameter, so users don't have to select it manually.
内容的提问来源于stack exchange,提问作者Rashid Aziz

