You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django报错IntegrityError: music_song.album_id不可为NULL求排查

Fixing the 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:

  1. Fetch the Album from the URL parameter
    Your view already receives a pk from 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 use get_object_or_404 to safely grab the Album instance—it returns a 404 page if the Album doesn't exist, which is cleaner than a raw error.

  2. Link the Song to the Album before saving
    When your form is valid, don't save it immediately. Use commit=False to 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_404 ensures we have a valid Album that matches the URL's pk.
  • form.save(commit=False) lets us tweak the Song object before writing it to the database—this is where we set the mandatory album field.
  • When we call song.save() after assigning the album, the album_id field will have a valid value, so the database won't throw the IntegrityError anymore.

Quick sanity checks:

  • Verify the URL's pk points to an existing Album (you can check this in the Django admin panel).
  • Your SongForm doesn't need to include the album field (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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:14:29