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

Django生成二维码无法存入数据库及保存路径问题求助

解决Django信号生成用户二维码的两个问题

问题1:用户创建时不生成Account对象

导致该问题的核心原因有三个,逐个修复:

  1. 信号未注册
    Django信号需要在app的apps.py中注册才能触发,打开对应app的apps.py修改如下:

    from django.apps import AppConfig
    
    class YourAppConfig(AppConfig):
        default_auto_field = 'django.db.models.BigAutoField'
        name = 'your_app_name'
    
        def ready(self):
            # 导入signals确保信号被注册
            import your_app_name.signals
    

    同时在settings.py的INSTALLED_APPS中,将原app名称替换为your_app_name.apps.YourAppConfig。

  2. account_id字段类型不匹配
    你生成的是20位数字字符串,但模型中account_id用了IntegerField——Django的IntegerField最大仅支持10位数字(最大值2147483647),20位数字直接存储会报错,导致Account创建失败。修改模型:

    class Account(models.Model):
        user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
        qr_code = models.ImageField(upload_to='qrcode')
        # 改为CharField并指定长度20
        account_id = models.CharField(max_length=20, unique=True)
    
  3. qr_code字段赋值错误
    ImageField无法直接接收qrcode生成的Image对象,需要将图片转换为Django可识别的File对象。

问题2:二维码保存到项目根目录而非指定文件夹

直接使用img.save('default.png')会将文件存在项目根目录,且所有用户的二维码会互相覆盖。正确做法是利用Django媒体文件系统,将图片保存到MEDIA_ROOT/qrcode目录下,每个用户使用唯一文件名。

修改后的signals.py完整代码

import random
import string
import io
import qrcode
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.files.base import File
from .models import Account
from django.contrib.auth import get_user_model

User = get_user_model()

@receiver(post_save, sender=User)
def create_account(sender, instance, created, **kwargs):
    if created:
        # 生成20位数字字符串作为account_id
        random_number = ''.join(random.choices(string.digits, k=20))
        # 生成二维码(可替换为用户相关内容,比如用户ID)
        img = qrcode.make(f'user_{instance.id}_{random_number}')
        
        # 将图片转为字节流
        img_io = io.BytesIO()
        img.save(img_io, format='PNG')
        img_io.seek(0)  # 回到流的起始位置
        
        # 生成唯一文件名
        filename = f'qr_{random_number}.png'
        
        # 创建Account对象,用File包装字节流赋值给qr_code
        Account.objects.create(
            user=instance,
            qr_code=File(img_io, name=filename),
            account_id=random_number
        )

配置媒体文件路径

在settings.py中添加以下配置,确保媒体文件存储和访问正常:

import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

同时在项目根目录的urls.py中添加媒体文件路由:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 你的其他路由配置
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

修改完成后,新用户创建时会自动生成Account对象,二维码会保存到media/qrcode目录下,每个用户的二维码使用唯一文件名,不会互相覆盖。

内容的提问来源于stack exchange,提问作者Adamu Abdulkarim Dee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:07:48