Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
21
respostas

Classe de View

A classe de view, só pode ter um metodo Get e outro Post ? Não pode ter mais de um para cada, de acordo com a rota ?

21 respostas

Oi, Thiago! Então, no básico, cada classe View vai ter um get e/ou post. O que fazemos, no geral, é uma classe diferente para cada rota (ou padrão de rota), para então definirmos essa view criada lá no urls.py, na variável urlpatterns.

Ok, e no caso avançado ? Usando Django Rest Framework, por exemplo ?

Desculpa a demora para responder, Thiago!

De qualquer forma, não sei se entendi muito bem a dúvida... Fica igual, com o Django Rest Framework ainda temos as class-based views e as views normais baseadas em funções.

Tudo bem, estou com outro problema, como faço pra retornar um arquivo zip no Response ? Já tentei de tudo

Thiago, você tem que avisar para o navegador que quer tratar a resposta como um anexo de arquivo. Para isso, o melhor é usar diretamente o próprio HttpResponse, passando o atributo content_type para o construtor e alterando seu Content-Disposition.:

response = HttpResponse(arquivo_zip, content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename="arquivo.zip"'
return response

Só não esqueça de importar o HttpResponse do django.http.

zip_file_name = "meuteste.zip"       
zip_arch = ZipFile(zip_file_name, "w")

Eu devo passar no HttpResponde o zip_file_name ou zip_arch ?

Também não sei se é o melhor jeito de criar o arquivo .zip, mas é assim que eu fiz

zip_file_name = "meu.zip"       
zip_arch = ZipFile(zip_file_name, "w")
os.chdir("/home/)
for file in glob.glob("*.*"): 
    zip_arch.write(file)

Seria o próprio conteúdo do arquivo:

with open('meuteste.zip', 'r') as arquivo_zip:
    zip_conteudo = arquivo_zip.read()
response = HttpResponse(zip_conteudo, content_type='application/zip')

Você pode usar o método .read() no próprio objeto ZipFile, se quiser, só lembre de abri-lo com o mode 'r' (ou 'r+') de leitura.

"Você pode usar o método .read() no próprio objeto ZipFile, se quiser, só lembre de abri-lo com o mode 'r' (ou 'r+') de leitura."

Onde seria ?

Opa, Thiago, desculpa, me enganei! Tem que usar o .read() abrindo com o open() normal, como eu mostreina penúltima resposta. Isso dentro do(s) método(s) da classe view

Bom dia amigo, quando eu uso o cURL para fazer a requisição e receber o arquivo zip ele retorna vazio e quando abro ele é informado "ocorreu um error ao abrir o pacote" Este é o comando que estou usando para a requisição.

curl -X POST   http://localhost:8000/xml/   -F file_received=@/home/file2.xml -o meu_box1.zip

Meu S.O. é linux.

Não estou conseguindo retornar arquivo .tar.gz também

Como está seu código de view? E .tar.gz tem o tipo MIME diferente, então tem que mudar o parâmetro content_type para 'application/gzip'.

Atualmente está assim :

        import tarfile
        zip_file_name = 'file.tar.gz'   
        all_path = "/home/"
        complete_path_of_file = all_path+zip_file_name

        zip_arch = tarfile.open(complete_path_of_file, "w:gz")

        os.chdir("/home/"+folder_to_zip)
        for file in glob.glob("*.*"): 
            zip_arch.add(file)
        zip_arch.close()
        zip_arch = tarfile.open(complete_path_of_file, "r")
        response = HttpResponse(zip_arch, content_type='application/x-gzip')
        response['Content-Disposition'] = 'attachment; filename="'+zip_file_name
        zip_arch.close()
        return response

Nem usando o cURL acima ou o postman, consigo receber o arquivo desejado.

Tenta mudar essas linhas:

zip_arch = tarfile.open(complete_path_of_file, "r")
response = HttpResponse(zip_arch, content_type='application/x-gzip')

para essas:

zip_arch = open(complete_path_of_file, 'r')
zip_arch_content = zip_arch.read()
response = HttpResponse(zip_arch_content, content_type='application/x-gzip')
Internal Server Error: /api/xml/
Traceback (most recent call last):
  File "/home/thiagod/.local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/thiagod/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/thiagod/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/thiagod/.local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/thiagod/.local/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/thiagod/.local/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
    response = self.handle_exception(exc)
  File "/home/thiagod/.local/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/thiagod/.local/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/thiagod/python/apibox/receiver/views.py", line 48, in post
    return self.create_zip(request,project_name,folder_to_zip, extension_file)
  File "/home/thiagod/python/apibox/receiver/views.py", line 82, in create_zip
    zip_arch_content = zip_arch.read()
  File "/usr/lib/python3.6/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

Seguindo suas alterações deu esse error

solução!

Opa, é que o Python 3 tenta dar um decode automaticamente quando lê de um arquivo. Tem que avisar ele que queremos ler como bytes, então muda essa linha:

zip_arch = open(complete_path_of_file, 'r')

para:

zip_arch = open(complete_path_of_file, 'rb')

Nossa, deu tudo certo, vlw por tudo! e pela incrível paciência, espero demorar a retornar aqui com dúvidas, e quando retornar que você me ajude kkk

Opa, Thiago, fico felizão que deu tudo certo! Tópicos assim são muito legais, porque a galera que vê depois acaba não precisando passar os perrengues que a gente passou antes, aí ajuda bastante gente!

E lembrando que dúvidas são essenciais pros nossos estudos, então não deixa de vir aqui no fórum quando surgir uma! Abraços e bons estudos!