[django] 장고에서 파일을 업로드하는 방법? [닫은]

Django의 초보자로서 Django 1.3에서 업로드 앱을 만드는 데 어려움이 있습니다. 최신 예제 / 스 니펫을 찾을 수 없습니다. 누군가가 최소한이지만 완전한 (Model, View, Template) 예제 코드를 게시 할 수 있습니까?



답변

휴, 장고 문서에는 실제로 이것에 대한 좋은 예가 없습니다. 나는 이것이 작동하는 방식을 이해하기 위해 모든 조각을 파기 위해 2 시간 이상을 보냈습니다. 그 지식을 바탕으로 파일을 업로드하고 목록으로 표시 할 수있는 프로젝트를 구현했습니다. 프로젝트의 소스를 다운로드하려면 https://github.com/axelpale/minimal-django-file-upload-example을 방문 하거나 복제하십시오.

> git clone https://github.com/axelpale/minimal-django-file-upload-example.git

업데이트 2013-01-30 : GitHub 소스는 1.3 외에도 Django 1.4를 구현했습니다. 몇 가지 변경 사항이 있지만 다음 자습서는 1.4에도 유용합니다.

업데이트 2013-05-10 : GitHub의 Django 1.5 구현. urls.py에서 리디렉션의 사소한 변경 및 list.html에서 URL 템플릿 태그의 사용법. 노력해 주신 hubert3 에게 감사합니다 .

2013-12-07 업데이트 : GitHub에서 Django 1.6이 지원됩니다. myapp / urls.py에서 하나의 가져 오기가 변경되었습니다. Arthedian 에게 감사드립니다 .

2015-03-17 업데이트 : aronysidoro 덕분에 GitHub에서 Django 1.7이 지원되었습니다 .

2015-09-04 업데이트 : nerogit 덕분에 GitHub에서 Django 1.8이 지원되었습니다 .

업데이트 2016-07-03 : daavvenerogit 덕분에 GitHub에서 Django 1.9 지원

프로젝트 트리

업로드 용 단일 앱 및 미디어 / 디렉토리가있는 기본 Django 1.3 프로젝트입니다.

minimal-django-file-upload-example/
    src/
        myproject/
            database/
                sqlite.db
            media/
            myapp/
                templates/
                    myapp/
                        list.html
                forms.py
                models.py
                urls.py
                views.py
            __init__.py
            manage.py
            settings.py
            urls.py

1. 설정 : myproject / settings.py

파일을 업로드하고 제공하려면 Django가 업로드 한 파일을 저장하는 위치와 파일을 제공하는 URL을 지정해야합니다. MEDIA_ROOT 및 MEDIA_URL은 기본적으로 settings.py에 있지만 비어 있습니다. 자세한 내용은 Django 파일 관리 의 첫 번째 줄 을 참조하십시오. 데이터베이스를 설정하고 INSTALLED_APPS에 myapp를 추가하십시오.

...
import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
...
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'database.sqlite3'),
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}
...
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
...
INSTALLED_APPS = (
    ...
    'myapp',
)

2. 모델 : myproject / myapp / models.py

다음으로 FileField가있는 모델이 필요합니다. 이 특정 필드는 현재 날짜 및 MEDIA_ROOT에 따라 파일을 미디어 / 문서 / 2011 / 12 / 24 /에 저장합니다. FileField 참조를 참조 하십시오 .

# -*- coding: utf-8 -*-
from django.db import models

class Document(models.Model):
    docfile = models.FileField(upload_to='documents/%Y/%m/%d')

3. 양식 : myproject / myapp / forms.py

업로드를 잘 처리하려면 양식이 필요합니다. 이 양식에는 하나의 필드 만 있지만 충분합니다. 자세한 내용은 양식 FileField 참조 를 참조하십시오.

# -*- coding: utf-8 -*-
from django import forms

class DocumentForm(forms.Form):
    docfile = forms.FileField(
        label='Select a file',
        help_text='max. 42 megabytes'
    )

4.보기 : myproject / myapp / views.py

모든 마술이 일어나는 전망. request.FILES취급 방법 에 주의하십시오 . 저에게는 모델에 request.FILES['docfile']저장할 수있는 사실을 발견하기가 정말 어려웠습니다 . 모델의 save ()는 파일 시스템에 파일 저장을 자동으로 처리합니다.

# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

from myproject.myapp.models import Document
from myproject.myapp.forms import DocumentForm

def list(request):
    # Handle file upload
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = Document(docfile = request.FILES['docfile'])
            newdoc.save()

            # Redirect to the document list after POST
            return HttpResponseRedirect(reverse('myapp.views.list'))
    else:
        form = DocumentForm() # A empty, unbound form

    # Load documents for the list page
    documents = Document.objects.all()

    # Render list page with the documents and the form
    return render_to_response(
        'myapp/list.html',
        {'documents': documents, 'form': form},
        context_instance=RequestContext(request)
    )

5. 프로젝트 URL : myproject / urls.py

Django는 기본적으로 MEDIA_ROOT를 제공하지 않습니다. 프로덕션 환경에서는 위험 할 수 있습니다. 그러나 개발 단계에서는 단축 할 수있었습니다. 마지막 줄에주의하십시오. 이 줄을 통해 Django는 MEDIA_URL에서 파일을 제공 할 수 있습니다. 이것은 개발 단계에서만 작동합니다.

자세한 내용은 django.conf.urls.static.static 참조 를 참조하십시오. 미디어 파일 제공에 대한이 토론을 참조하십시오 .

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    (r'^', include('myapp.urls')),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

6. 앱 URL : myproject / myapp / urls.py

보기에 액세스 할 수있게하려면 URL을 지정해야합니다. 여기서 특별한 것은 없습니다.

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url

urlpatterns = patterns('myapp.views',
    url(r'^list/$', 'list', name='list'),
)

7. 템플릿 : myproject / myapp / templates / myapp / list.html

마지막 부분 : 목록의 템플릿과 그 아래의 업로드 양식. Django에 업로드하려면 양식에 enctype-attribute가 “multipart / form-data”로 설정되고 메소드가 “post”로 설정되어 있어야합니다. 자세한 내용은 파일 업로드 설명서 를 참조하십시오.

FileField에는 템플릿에서 사용할 수있는 많은 속성이 있습니다. 예를 들어 템플릿에서와 같이 {{document.docfile.url}} 및 {{document.docfile.name}}입니다. 모델 에서 파일 사용 기사파일 오브젝트 문서 에서 이에 대한 자세한 내용을 참조하십시오 .

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Minimal Django File Upload Example</title>   
    </head>
    <body>
    <!-- List of uploaded documents -->
    {% if documents %}
        <ul>
        {% for document in documents %}
            <li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a></li>
        {% endfor %}
        </ul>
    {% else %}
        <p>No documents.</p>
    {% endif %}

        <!-- Upload form. Note enctype attribute! -->
        <form action="{% url 'list' %}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>{{ form.non_field_errors }}</p>
            <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
            <p>
                {{ form.docfile.errors }}
                {{ form.docfile }}
            </p>
            <p><input type="submit" value="Upload" /></p>
        </form>
    </body>
</html> 

8. 초기화

syncdb와 runserver를 실행하십시오.

> cd myproject
> python manage.py syncdb
> python manage.py runserver

결과

마지막으로 모든 것이 준비되었습니다. Django 기본 개발 환경에서는 업로드 된 문서 목록을에서 볼 수 있습니다 localhost:8000/list/. 오늘 파일은 / path / to / myproject / media / documents / 2011 / 12 / 17 /에 업로드되고 목록에서 열 수 있습니다.

이 답변이 도움이 될만큼 많은 사람을 도울 수 있기를 바랍니다.


답변

일반적으로 ‘실제로 예제를 얻으려고 할 때’코드 작성을 시작하는 것이 가장 좋습니다. 여기에 도움이되는 코드가 없으므로 질문에 대한 답변이 훨씬 많아집니다.

파일을 가져 오려면 html 파일 어딘가에 다음과 같은 것이 필요합니다.

<form method="post" enctype="multipart/form-data">
    <input type="file" name="myfile" />
    <input type="submit" name="submit" value="Upload" />
</form>

그러면 탐색 버튼, 작업을 시작하기위한 업로드 버튼 (양식 제출) 및 Django가 사용자에게 제공하는 enctype을 기록합니다 request.FILES

어딘가에서보기를 사용하여 파일에 액세스 할 수 있습니다

def myview(request):
    request.FILES['myfile'] # this is my file

파일 업로드 문서 에 엄청난 양의 정보가 있습니다

페이지를 철저히 읽고 코드 작성을 시작한 다음 작동하지 않을 때 예제와 스택 추적으로 돌아 오십시오.


답변

데모

장고 3과 함께 작동 하는 github repo 참조

최소 장고 파일 업로드 예제

1. 장고 프로젝트 만들기

startproject ::를 실행하십시오.

$ django-admin.py startproject sample

이제 폴더 ( sample )가 생성됩니다.

2. 앱 만들기

앱 만들기 ::

$ cd sample
$ python manage.py startapp uploader

이제이 uploader파일들을 가진 폴더 ( )가 생성됩니다 :

uploader/
  __init__.py
  admin.py
  app.py
  models.py
  tests.py
  views.py
  migrations/
    __init__.py

3. settings.py 업데이트

sample/settings.py추가 'uploader'INSTALLED_APPS및 추가 MEDIA_ROOT하고 MEDIA_URL, 즉 ::

INSTALLED_APPS = [
    'uploader',
    ...<other apps>...      
]

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

4. urls.py 업데이트

sample/urls.py추가 ::

...<other imports>...
from django.conf import settings
from django.conf.urls.static import static
from uploader import views as uploader_views

urlpatterns = [
    ...<other url patterns>...
    path('', uploader_views.UploadView.as_view(), name='fileupload'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

5. models.py 업데이트

업데이트 uploader/models.py::

from django.db import models
class Upload(models.Model):
    upload_file = models.FileField()    
    upload_date = models.DateTimeField(auto_now_add =True)

6. views.py 업데이트

업데이트 uploader/views.py::

from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Upload
class UploadView(CreateView):
    model = Upload
    fields = ['upload_file', ]
    success_url = reverse_lazy('fileupload')
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['documents'] = Upload.objects.all()
        return context

7. 템플릿 만들기

sample / uploader / templates / uploader 폴더 생성

파일을 작성 upload_form.htmlsample/uploader/templates/uploader/upload_form.html::

<div style="padding:40px;margin:40px;border:1px solid #ccc">
    <h1>Django File Upload</h1>
    <form method="post" enctype="multipart/form-data">
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">Submit</button>
    </form><hr>
    <ul>
    {% for document in documents %}
        <li>
            <a href="{{ document.upload_file.url }}">{{ document.upload_file.name }}</a>
            <small>({{ document.upload_file.size|filesizeformat }}) - {{document.upload_date}}</small>
        </li>
    {% endfor %}
    </ul>
</div>

8. 데이터베이스 동기화

데이터베이스와 실행 서버를 동기화합니다 ::

$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver

http : // localhost : 8000 /을 방문 하십시오.


답변

django에서 혼란스러운 문서를 발견했다고 말해야합니다. 또한 가장 간단한 예를 들어 왜 양식이 언급됩니까? views.py에서 작업 해야하는 예는 다음과 같습니다.

for key, file in request.FILES.items():
    path = file.name
    dest = open(path, 'w')
    if file.multiple_chunks:
        for c in file.chunks():
            dest.write(c)
    else:
        dest.write(file.read())
    dest.close()

html 파일은 아래 코드와 비슷하지만이 예제에서는 하나의 파일 만 업로드하고 파일을 저장하는 코드는 많은 것을 처리합니다.

<form action="/upload_file/" method="post" enctype="multipart/form-data">{% csrf_token %}
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>

이 예제는 내 코드가 아니며 내가 찾은 두 개의 다른 예제와 반대되었습니다. 나는 django의 상대적 초보자이므로 핵심 포인트가 누락되었을 가능성이 큽니다.


답변

나도 비슷한 요구 사항이 있었다. net에 대한 대부분의 예제는 모델을 만들고 사용하고 싶지 않은 양식을 작성하도록 요청합니다. 마지막 코드는 다음과 같습니다.

if request.method == 'POST':
    file1 = request.FILES['file']
    contentOfFile = file1.read()
    if file1:
        return render(request, 'blogapp/Statistics.html', {'file': file1, 'contentOfFile': contentOfFile})

그리고 HTML로 업로드하여 작성했습니다.

{% block content %}
    <h1>File content</h1>
    <form action="{% url 'blogapp:uploadComplete'%}" method="post" enctype="multipart/form-data">
         {% csrf_token %}
        <input id="uploadbutton" type="file" value="Browse" name="file" accept="text/csv" />
        <input type="submit" value="Upload" />
    </form>
    {% endblock %}

다음은 파일 내용을 표시하는 HTML입니다.

{% block content %}
    <h3>File uploaded successfully</h3>
    {{file.name}}
    </br>content = {{contentOfFile}}
{% endblock %}


답변

Henry의 예를 확장 :

import tempfile
import shutil

FILE_UPLOAD_DIR = '/home/imran/uploads'

def handle_uploaded_file(source):
    fd, filepath = tempfile.mkstemp(prefix=source.name, dir=FILE_UPLOAD_DIR)
    with open(filepath, 'wb') as dest:
        shutil.copyfileobj(source, dest)
    return filepath

handle_uploaded_file업로드 된 파일 객체를 사용하여보기 에서이 함수를 호출 할 수 있습니다 . 파일 시스템에 고유 한 이름 (원래 업로드 된 파일의 파일 이름이 접두사)로 파일을 저장하고 저장된 파일의 전체 경로를 반환합니다. 데이터베이스에 경로를 저장하고 나중에 파일로 무언가를 수행 할 수 있습니다.


답변

models.py에서 파일 필드를 만듭니다.

파일을 업로드하는 경우 (admin.py에서) :

def save_model(self, request, obj, form, change):
    url = "http://img.youtube.com/vi/%s/hqdefault.jpg" %(obj.video)
    url = str(url)

    if url:
        temp_img = NamedTemporaryFile(delete=True)
        temp_img.write(urllib2.urlopen(url).read())
        temp_img.flush()
        filename_img = urlparse(url).path.split('/')[-1]
        obj.image.save(filename_img,File(temp_img)

템플릿에서 해당 필드를 사용하십시오.