上载没有ModelForm的图像

时间:2019-10-05 18:51:51

标签: python django

我正在创建一个页面,用于将产品添加到用户的网上商店,并且在上传图片时遇到麻烦。

我有一个带有pip install --target=C:\path\to\folder\ opencv-python的表单,选择文件后,文件(图像)应暂时上传到服务器。上传完成后,应显示图像预览。在上载期间,还应显示正在加载带有客户端进度指示的微调GIF,以及取消上载的选项。上传后,每个上传的图片都应有一个删除选项。

由于所有这些和其他原因,我没有使用ModelForm,而是手动创建了所有内容。

因此,我的计划是将onchange侦听器附加到该输入,并且在选择文件后,将从JavaScript发送POST XMLHttpRequest,这将调用一个视图,该视图会将图像保存到某种类型的表中以用于临时上传的图像,而该行的ID类似于<input type="file">,但有些不同。我用这种方法的问题是生成该会话密钥,该会话密钥应该是唯一的,并且只要打开页面它就应该持续。因此,刷新页面将意味着生成一个新密钥。 request.session.session_key不符合我的需求,因为在整个会话过程中保持不变。提交完整表格后,我计划以某种方式将这些临时上传的图片与我的主要产品实例相关联,并从表格中删除它们以获取临时图片。

您如何看待该解决方案?如果可行,如何生成密钥?

@EDIT:

request.session.session_key

models.py

1 个答案:

答案 0 :(得分:0)

我使用Angular做过类似的事情

products.ts

onFileChanged(event) {
    let reader = new FileReader();
    let me = this;
    if (event.target.files.length > 0) {
      const file = event.target.files[0];
      reader.readAsDataURL(file);
      reader.onload = function () {
          me.imagen = reader.result;
      };
      reader.onerror = function (error) {
        console.log('Error: ', error);
      };
    }
}

onSubmit(f){
   // f is my form 
   let postdata=f.value;
   postdata.imagen={'imagen': this.imagen};
   postdata.usuario=+localStorage.getItem("id_usuario");
   postdata.categoria=+postdata.categoria;
   postdata.precio=+postdata.precio;
   postdata.donacion=+postdata.donacion;
   console.log(postdata);
   this.articuloServicio.postNuevoArticulo(postdata)
   .subscribe(res=>{
     this.router.navigateByUrl('/mis_productos')
   },(error=>{
      alert('Error, verifique la informacion ingresada');
   }));
}

models.py

class Image(models.Model):
    image=models.ImageField(upload_to='imagenes/',blank=False, null=False)
    articule=models.ForeignKey(Articule,on_delete=models.CASCADE,
    related_name="images", 
    null=False, blank=False)

某些图片可能用于同一商品

serializers.py

class ArticuloSerializer(serializers.ModelSerializer):

imagen = ImagenCreateSerializer(write_only=True)
class Meta:
    model = Articulo
    fields = ('id', 'categoria','usuario','nombre','precio','donacion','descrip', 'imagen')

def create(self, validated_data):
    imagenes = validated_data.pop('imagen')
    articulo = Articulo(**validated_data)
    articulo.save()
    for imagen in imagenes.values():
        Imagen.objects.create(articulo=articulo, imagen=imagen)
    return articulo

views.py

class ArticulosList(generics.ListCreateAPIView):

queryset = Articulo.objects.all()
serializer_class = ArticuloSerializer
def list(self, request, *args, **kwargs):
    queryset = Articulo.objects.all()
    serializer = ArticuloSerializerDetail(queryset, context={'request': request}, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)

def create(self, request, *args, **kwargs):
    serializer = ArticuloSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

products.ts中:在onFileChanged(用于管理文件上传)中,我使用Filereader来获取分配给 Angular组件中的变量。在onSubmit中,我从表单f和图像中获取数据,所有数据都位于一个对象中 将通过POST请求发送到我的服务中。

models.py中,我共享我的图像模型,该模型附加到Articule,也就是我的模式中的其他模型。图像字段是 ImageField来自Django。

serializers.py中,我分享了ArticuleSerializer,该序列化了Articule获取和发布视图的数据。如你看到的 有一个create函数,您可以定义发布请求时如何管理数据。

views.py中,我定义了用于获取和发布的Articule视图,用于发布的是create函数。调用该视图 在您的urls.py中将其分配为

path("endpoint/", ArticuleList.as_view({"get": "list", "post": "create"}))