Django Rest与Angular 5图片上传技术问询:表单图片获取与数据传递
完善Angular 5 + Django Rest Framework图片上传功能
看起来你已经拿到了前端的文件对象,接下来我们需要把表单数据和图片一起打包发送到后端,同时在Django Rest这边做好接收和存储的准备。我分两部分给你详细说明:
一、Angular 5 前端代码完善
首先,你需要修改CreateDetailProduct方法,用FormData来封装文件和表单字段——这是上传文件的标准做法,因为它能正确处理二进制文件数据。同时我们可以加一点文件类型验证,避免用户上传非图片文件。
1. 完善文件选择方法(加类型验证)
handleFileInput(file: FileList) { const selectedFile = file.item(0); // 只允许常见图片格式 const allowedImageTypes = ['image/jpeg', 'image/png', 'image/gif']; if (selectedFile && allowedImageTypes.includes(selectedFile.type)) { this.fileToUpload = selectedFile; } else { alert('请选择有效的图片文件(JPG/PNG/GIF)'); // 清空无效的文件选择 const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement; fileInput.value = ''; } }
2. 重构CreateDetailProduct方法(发送FormData)
// 记得先导入HttpClient import { HttpClient } from '@angular/common/http'; // 在组件构造函数注入HttpClient constructor(private http: HttpClient) {} CreateDetailProduct(){ // 初始化FormData对象 const formData = new FormData(); // 添加图片文件(如果有选择文件) if (this.fileToUpload) { formData.append('image', this.fileToUpload, this.fileToUpload.name); } // 提取表单值并添加到FormData const formValues = this.FormDetailProductCreate.value; formData.append('Id_Product', formValues.Id_Product.id.toString()); formData.append('Id_TypeProduct', formValues.Id_TypeProduct.id.toString()); formData.append('Id_Provider', formValues.Id_Provider.id.toString()); formData.append('TotalPrice', formValues.TotalPrice.toString()); formData.append('Quantity', formValues.Quantity.toString()); // 发送POST请求到Django后端API this.http.post('/api/detailproducts/', formData) .subscribe( (response) => { console.log('产品详情及图片上传成功!', response); // 这里可以添加成功后的逻辑:比如重置表单、跳转到列表页 this.FormDetailProductCreate.reset(); const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement; fileInput.value = ''; this.fileToUpload = null; }, (error) => { console.error('上传失败,请检查错误信息:', error); // 可以在这里给用户显示错误提示 } ); }
3. 模板中的文件输入绑定
确保你的模板里有对应的文件输入控件,绑定handleFileInput方法:
<input type="file" class="form-control" (change)="handleFileInput($event.target.files)">
二、Django Rest Framework 后端配置
接下来需要在Django这边配置模型、序列化器和视图,来接收并存储图片和表单数据。
1. 模型添加图片字段
假设你的DetailProduct模型还没有图片字段,先添加ImageField:
from django.db import models class DetailProduct(models.Model): Id_Product = models.ForeignKey(Product, on_delete=models.CASCADE) Id_TypeProduct = models.ForeignKey(TypeProduct, on_delete=models.CASCADE) Id_Provider = models.ForeignKey(Provider, on_delete=models.CASCADE) TotalPrice = models.DecimalField(max_digits=10, decimal_places=2) Quantity = models.IntegerField() # 添加图片字段,upload_to指定存储路径(会在media目录下创建这个文件夹) image = models.ImageField(upload_to='detail_product_images/', blank=True, null=True)
2. 配置媒体文件存储
在settings.py里添加媒体文件的配置,这样Django才能正确存储和访问上传的图片:
import os # 媒体文件根目录 MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 媒体文件访问URL MEDIA_URL = '/media/'
同时在项目根目录的urls.py里添加媒体文件的路由(仅开发环境使用,生产环境建议用Nginx等托管):
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 你的其他路由... ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
3. 编写序列化器
创建支持文件上传的序列化器:
from rest_framework import serializers from .models import DetailProduct class DetailProductSerializer(serializers.ModelSerializer): class Meta: model = DetailProduct fields = ['Id_Product', 'Id_TypeProduct', 'Id_Provider', 'TotalPrice', 'Quantity', 'image']
4. 编写视图处理上传请求
用CreateAPIView快速实现创建接口,它会自动处理FormData格式的请求:
from rest_framework import generics, status from .models import DetailProduct from .serializers import DetailProductSerializer class DetailProductCreateView(generics.CreateAPIView): queryset = DetailProduct.objects.all() serializer_class = DetailProductSerializer
然后把这个视图添加到你的应用urls.py里:
from django.urls import path from .views import DetailProductCreateView urlpatterns = [ path('detailproducts/', DetailProductCreateView.as_view(), name='detailproduct-create'), ]
5. 解决跨域问题(如果Angular和Django不在同一端口)
如果你的Angular前端运行在localhost:4200,Django在localhost:8000,需要配置CORS:
- 安装依赖:
pip install django-cors-headers - 在
settings.py里添加中间件和允许的源:
INSTALLED_APPS = [ # 其他应用... 'corsheaders', ] MIDDLEWARE = [ # 放在最前面或者靠近顶部的位置 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # 其他中间件... ] # 允许Angular所在的域名访问 CORS_ALLOWED_ORIGINS = [ "http://localhost:4200", ]
几个注意事项
- 确保安装了Pillow库:
pip install pillow,Django需要它来处理图片文件。 - 可以在Django的
settings.py里配置文件大小限制:比如FILE_UPLOAD_MAX_MEMORY_SIZE = 5242880(5MB)。 - 生产环境不要用Django托管媒体文件,建议用云存储或者Nginx来处理。
内容的提问来源于stack exchange,提问作者Sergio Lopez
相关产品推荐
相关产品推荐

