如何在Django Rest Framework中处理文件?

问题描述 投票:1回答:2

我正在构建Angular + Django项目,我需要向其中添加一些文件,这个想法是该模型Ticket应该接收一些文件,例如imgs或pdf ...我应该在模型中使用Wich Field吗? FileField?

class Ticket (models.Model):
    titulo = models.CharField(max_length=100, blank=True)
    estagio = models.ForeignKey(
        Estagio, related_name='tickets', on_delete=models.CASCADE, null=True)
    cliente = models.ForeignKey(Cliente, on_delete=models.CASCADE, null=True)
    org = models.ForeignKey(Organizacao, on_delete=models.CASCADE, null=True)
    produto = models.ManyToManyField(Produto)
    valorestimado = models.IntegerField(null=True)
    termometro = models.CharField(max_length=100, null=True, blank=True)
    vendedor = models.ForeignKey(
        Vendedor,  on_delete=models.CASCADE, null=True)
    vendedorext = models.ManyToManyField(
        VendedorExt, related_name='leads', blank=True)
    obs = models.ManyToManyField(Obs, related_name='tickets')
    status = models.CharField(max_length=155, blank=True, default='Aberto')
    mtvperd = models.CharField(max_length=155, null=True, blank=True)
    cmtperd = models.CharField(max_length=155, null=True, blank=True)
    created = models.ForeignKey(Created, on_delete=models.CASCADE, null=True)
    updated = models.ManyToManyField(Updated)

    def __str__(self):
        return str(self.titulo)

而且我该如何在视图中处理此img? :

class TicketViewSet(viewsets.ModelViewSet):

    queryset = Ticket.objects.all().order_by('-id')
    serializer_class = TicketSerializer
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

    def create(self, request):
        data = request.data

        print(data['titulo'])
        print(request.user)
        print(request.headers)

        c = Created()
        c.user = request.user
        c.save()
        V = Vendedor.objects.get(id=int(data['vendedor']))
        print(V)

        T = Ticket()
        T.titulo = data['titulo']
        T.estagio = Estagio.objects.get(id=int(data['estagio']))
        T.cliente = Cliente.objects.get(id=int(data['cliente']))
        T.org = Organizacao.objects.get(id=int(data['org']))
        T.valorestimado = int(data['valorestimado'])
        T.termometro = data['termometro']
        T.vendedor = V
        T.status = 'Aberto'

        T.created = c
        T.save()
        try:
            if data['obs'].length >= 1:
                for i in data['obs']:
                    k = Obs()
                    k.texto = i
                    k.save()
                    T.obs.add(k)
                    T.save()
        except:
            k = Obs()
            k.texto = data['obs']
            k.save()
            T.obs.add(k)
            T.save()

        produtos = data['produto']
        for prod in produtos:
            T.produto.add(Produto.objects.get(id=prod))

        T.save()
        print(data)
        return JsonResponse({'message': 'Saved'})

而且,这是将文件发送到api的正确方法吗?

              <form>
                <label id="thumbnail">
                  <input type="file" name="attachments[dummy][file]"  class="file_selector" multiple="multiple"/>
                </label>
                <button class="btn btn-success" (click)="formAnexo()" style="float: right;">Salvar Anexo</button>
              </form>

很抱歉,如果我错过明显的事情,那是第一次使用django处理文件

django angular django-models django-rest-framework django-views
2个回答
1
投票

如果必须将多个文件附加到同一资源,我建议创建一个单独的表。例如,如果您要将几张图片上传到票务资源,则可以执行以下操作:

class Photo(models.Model):
    file = models.ImageField(
        upload_to='photos',
        null=False,
        max_length=100
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        db_index=True
    )

    class Meta:
        ordering = ['-created_at']

然后在票证模型上定义:

class Ticket(models.Model):
    photos = models.ManyToManyField(
        'app_label.Photo',
        blank=True,
        related_name='ticket_photos'
    )
    ...

为了存储照片,我将研究像AWS S3这样的解决方案,该解决方案非常容易使用Django storages进行设置。

[为了使用Angular在前端上传图片,您需要使用FormData API并以multipart/form-data的形式上传数据。

这里是代码示例:

@Injectable({ providedIn: 'root' })
export class MyService {

  constructor(
    private _http: HttpClient
  ) { }

  postFile(path: string, file: File, data?: any): Observable<any> {
    const uploadData = new FormData();
    uploadData.append('file', file, file.name);

    if (data) {
      Object.keys(data).forEach(key => {
        uploadData.append(key, data[key]);
      });
    }
    return this._http.post(
      path,
      uploadData
    );
  }
}

我希望这会帮助您入门。


0
投票

您必须在视图中使用FileUploadParser。https://www.django-rest-framework.org/api-guide/parsers/#basic-usage-example

parser_classes = (FileUploadParser,)

该模型的FileField将会确定

© www.soinside.com 2019 - 2024. All rights reserved.