likes
comments
collection
share

Django 实现用户需求及反馈系统并支持图片上传

作者站长头像
站长
· 阅读数 62

Django 实现用户需求及反馈系统并支持图片上传

在这篇博客中,我们将介绍如何使用 Django 实现一个用户需求和反馈系统,支持用户上传图片,同时限制上传图片的总大小不超过 3MB。我们将从模型设计开始,然后编写表单和视图来处理用户请求和图片上传。

1. 模型设计

首先,我们设计三个模型:UserRequestUserRequestImageUserFeedback。这些模型分别表示用户需求、用户需求相关的图片和用户反馈。

from myapp.models import User
from django.db import models

class UserRequestImage(models.Model):
    user_request = models.ForeignKey('UserRequest', related_name='images', on_delete=models.CASCADE)
    image = models.ImageField(upload_to='user_requests/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

class UserFeedbackImage(models.Model):
    user_feedback = models.ForeignKey('UserFeedback', related_name='images', on_delete=models.CASCADE)
    image = models.ImageField(upload_to='user_feedbacks/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

class UserRequest(models.Model):
    """用户需求表"""
    PRIORITY_CHOICES = [
        (1, '非常低'),
        (2, '低'),
        (3, '常规'),
        (4, '高'),
        (5, '非常高'),
    ]
    STATUS_CHOICES = (
        (1, '待处理'),
        (2, '处理中'),
        (3, '已完成'),
    )
    title = models.CharField(max_length=255, verbose_name='需求标题')
    description = models.TextField(verbose_name='需求描述')
    user = models.ForeignKey('User', on_delete=models.CASCADE, verbose_name='用户')
    priority = models.IntegerField(choices=PRIORITY_CHOICES, default=2, verbose_name='优先级')
    status = models.IntegerField(choices=STATUS_CHOICES, default=1, verbose_name='状态')
    progress = models.IntegerField(default=0, verbose_name='进度')  # 新增进度字段
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

class UserFeedback(models.Model):
    """用户反馈建议表"""
    FEEDBACK_TYPE_CHOICES = (
        (1, '建议'),
        (2, '问题'),
        (3, '其他'),
    )
    STATUS_CHOICES = (
        (1, '待处理'),
        (2, '处理中'),
        (3, '已完成'),
    )
    content = models.TextField(verbose_name='反馈内容')
    user = models.ForeignKey('User', on_delete=models.CASCADE, verbose_name='用户')
    feedback_type = models.IntegerField(choices=FEEDBACK_TYPE_CHOICES, default=1, verbose_name='反馈类型')
    status = models.IntegerField(choices=STATUS_CHOICES, default=1, verbose_name='状态')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

在上述代码中,UserRequest 模型包含了用户需求的基本信息,而 UserRequestImage 模型用来保存与用户需求相关的图片。同样,UserFeedback 模型表示用户反馈,UserFeedbackImage 模型保存用户反馈相关的图片。

2. 表单设计

接下来,我们为模型创建表单,用于在视图中处理用户提交的数据。

from django import forms
from myapp.models import UserRequest, UserFeedback, UserRequestImage, UserFeedbackImage

class UserRequestForm(forms.ModelForm):
    class Meta:
        model = UserRequest
        fields = ['title', 'description', 'priority']

class UserRequestImageForm(forms.ModelForm):
    class Meta:
        model = UserRequestImage
        fields = ['image']

class UserFeedbackForm(forms.ModelForm):
    class Meta:
        model = UserFeedback
        fields = '__all__'

class UserFeedbackImageForm(forms.ModelForm):
    class Meta:
        model = UserFeedbackImage
        fields = ['image']

这些表单类将帮助我们在视图中验证和保存用户提交的数据。

3. 视图设计

最后,我们创建视图来处理用户请求,并确保上传图片的总大小不超过 3MB。

from django.http import JsonResponse, HttpResponseBadRequest
from django.views.decorators.csrf import csrf_exempt
from django.core.exceptions import ValidationError

# 定义最大文件大小限制(3MB)
MAX_TOTAL_FILE_SIZE = 3 * 1024 * 1024

@csrf_exempt
def create_user_request(request):
    if request.method == 'POST':
        userid = request.session["info"].get('id')
        form = UserRequestForm(request.POST)
        if form.is_valid():
            # 创建但不保存 UserRequest 实例
            user_request = form.save(commit=False)
            # 设置用户ID
            user_request.user_id = userid
            # 保存 UserRequest 实例
            user_request.save()

            images = request.FILES.getlist('images[]')
            total_size = sum(image.size for image in images)

            # 检查总大小是否超过限制
            if total_size > MAX_TOTAL_FILE_SIZE:
                res_data = {
                    "status": 1,
                    "msg": "总文件大小超过3MB的限制。",
                    "data": {}
                }
                return JsonResponse(res_data, status=400)

            for image in images:
                UserRequestImage.objects.create(user_request=user_request, image=image)
            res_data = {
                "status": 0,
                "msg": "用户请求创建成功。",
                "data": {}
            }
            return JsonResponse(res_data, status=201)
        
        res_data = {
            "status": 1,
            "msg": f"{form.errors}",
            "data": {}
        }
        return JsonResponse(res_data, status=400)
    
    res_data = {
        "status": 1,
        "msg": "无效请求方法",
        "data": {}
    }
    return JsonResponse(res_data, status=400)

在这个视图中,我们首先检查请求方法是否为 POST。然后,我们从 session 中获取用户 ID,并创建一个新的 UserRequest 实例。接着,我们获取上传的图片并计算总大小。如果总大小超过了 3MB,我们返回一个错误响应。否则,我们保存每张图片并返回一个成功响应。

总结

通过上述步骤,我们实现了一个支持用户需求和反馈的系统,并允许用户上传图片,同时限制上传图片的总大小不超过 3MB。

希望本文能够帮助你理解 Django 中的模型设计和文件上传功能,并且能够成功构建用户需求和反馈系统。如果有任何疑问或建议,欢迎随时提出!

转载自:https://juejin.cn/post/7374614838007447552
评论
请登录