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

Django迁移报错:users_classroom.class_code列不存在问题求助

Django迁移报错:no such column: users_classroom.class_code

这是我的第一个Django项目,我尝试为Classroom模型添加class_code属性——一个6位随机字符串,用于让用户通过它加入班级。我参考了随机字符串生成的代码实现,同时遵循Django官方文档中添加唯一字段的迁移步骤,但因为UUID过长,改成了用随机字符串。执行migrate命令时,收到错误:django.db.utils.OperationalError: no such column: users_classroom.class_code。

项目名为Project,应用名为users,相关文件如下:

Forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile, Classroom
from home.models import Announcements
class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']
         
        def clean_email(self):
            email = self.cleaned_data['email']
        #   if User.objects.filter(email=email).exists():
                
            #   raise forms.ValidationError('That email is in use. Please Log in or use a different Email')
            return email

class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email']

class ProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['image']

class ClassJoinForm(forms.ModelForm):
    class Meta:
        model = Classroom
        fields = ['classroom']

Models.py

from django.db import models
from django.contrib.auth.models import User
from PIL import Image
import random

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')
    

    def __str__(self):
        return f'{self.user.username} Profile'

    def save(self, *args, **kwargs):
        super(Profile, self).save(*args, **kwargs)

        img = Image.open(self.image.path).convert('RGB')

        if img.height > 300 or img.width > 300:
            output_size = (300, 300)
            img.thumbnail(output_size)
            img.save(self.image.path)

class Classroom(models.Model):
    classroom = models.OneToOneField(User, on_delete=models.CASCADE)

    def create_new_class_code():
        not_unique = True
        while not_unique:
            unique_ref = random.randint(1000000000, 9999999999)
            if not Classroom.objects.filter(class_code=unique_ref):
                not_unique = False
        return str(unique_ref)
    class_code = models.CharField(
            max_length = 6,
            blank=True,
            editable=False,
            unique=True,
            default="AAAAAA"
        )

    def __str__(self):
        return f'{self.classroom.username} Classroom'

    def save(self, *args, **kwargs):
        super(Classroom, self).save(*args, **kwargs)

迁移文件

0003_classroom_class_code.py

# Generated by Django 4.1.7 on 2023-03-27 00:29

from django.db import migrations, models
from django.contrib.auth.models import User
import users.models


class Migration(migrations.Migration):

    dependencies = [
        ('users', '0002_classroom'),
    ]

    operations = [
        migrations.AddField(
            model_name='classroom',
            name='class_code',
            field=models.CharField(blank=True, default=users.models.Classroom.create_new_class_code, editable=False, max_length=6, null=True),
        ),
    ]

0004_auto_20230326_1931.py

# Generated by Django 4.1.7 on 2023-03-27 00:31

from django.db import migrations
from django.contrib.auth.models import User

def create_new_class_code():
        not_unique = True
        while not_unique:
            unique_ref = random.randint(1000000000, 9999999999)
            if not Transaction.objects.filter(Referrence_Number=unique_ref):
                not_unique = False
        return str(unique_ref)

class Migration(migrations.Migration):

    dependencies = [
        ('users', '0003_classroom_class_code'),
    ]

    operations = [
        migrations.RunPython(create_new_class_code)
    ]

0005_auto_20230326_1931.py

# Generated by Django 4.1.7 on 2023-03-27 00:31

from django.db import migrations, models
from django.contrib.auth.models import User
from users.models import Classroom
import uuid

class Migration(migrations.Migration):

    dependencies = [
        ('users', '0004_auto_20230326_1931'),
    ]

    operations = [
        migrations.AlterField(
            model_name='classroom',
            name='class_code',
            field=models.CharField(blank=True, default=Classroom.create_new_class_code, editable=False, max_length=6, unique=True),
        )
    ]

0006_alter_classroom_class_code.py

# Generated by Django 4.1.7 on 2023-03-27 02:26

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('users', '0005_auto_20230326_1931'),
    ]

    operations = [
        migrations.AlterField(
            model_name='classroom',
            name='class_code',
            field=models.CharField(blank=True, default='AAAAAA', editable=False, max_length=6, unique=True),
        ),
    ]

我试过用sqlflush和flush命令清理数据库,但没效果,已经恢复了数据库文件。


问题原因及解决办法

1. 核心问题

  • 0004迁移文件致命错误:函数create_new_class_code引用了未定义的Transaction模型,字段名拼写错误,且未接收Django RunPython要求的apps和schema_editor参数,导致迁移执行失败,class_code字段根本没在数据库中创建。
  • 随机生成逻辑错误:模型中生成的是10位数字,与class_code的max_length=6冲突,且函数未定义为静态/类方法,调用逻辑异常。

修复步骤

步骤1:回滚迁移到0002版本

python manage.py migrate users 0002_classroom

步骤2:删除错误迁移文件

直接删除users/migrations目录下的0003、0004、0005、0006四个迁移文件。

步骤3:修正Models.py代码

from django.db import models
from django.contrib.auth.models import User
from PIL import Image
import random
import string

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')
    

    def __str__(self):
        return f'{self.user.username} Profile'

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        img = Image.open(self.image.path).convert('RGB')

        if img.height > 300 or img.width > 300:
            output_size = (300, 300)
            img.thumbnail(output_size)
            img.save(self.image.path)

class Classroom(models.Model):
    classroom = models.OneToOneField(User, on_delete=models.CASCADE)
    class_code = models.CharField(
            max_length=6,
            blank=True,
            editable=False,
            unique=True
        )

    @staticmethod
    def create_new_class_code():
        # 生成6位随机字母+数字组合
        chars = string.ascii_uppercase + string.digits
        while True:
            code = ''.join(random.choice(chars) for _ in range(6))
            if not Classroom.objects.filter(class_code=code).exists():
                return code

    def save(self, *args, **kwargs):
        # 仅当class_code为空时生成新代码
        if not self.class_code:
            self.class_code = self.create_new_class_code()
        super().save(*args, **kwargs)

    def __str__(self):
        return f'{self.classroom.username} Classroom'

步骤4:重新生成并执行迁移

python manage.py makemigrations users
python manage.py migrate users

内容的提问来源于stack exchange,提问作者Robel Abraham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:12:09