在这篇博客中,我们将介绍如何使用 Django 实现一个用户需求和反馈系统,支持用户上传图片,同时限制上传图片的总大小不超过 3MB。我们将从模型设计开始,然后编写表单和视图来处理用户请求和图片上传。
1. 模型设计
首先,我们设计三个模型:UserRequest、UserRequestImage 和 UserFeedback。这些模型分别表示用户需求、用户需求相关的图片和用户反馈。
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 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 中的模型设计和文件上传功能,并且能够成功构建用户需求和反馈系统。