Django File Upload Geniş Özet
Manuel File Upload
Veritabaninda herhangi bir ilgili alana kayit yapmadan sadece dosya upload etmenin nasil oldugunu gosterme amaciyla bu kismi ekliyorum. Tabii buradaki ornek kod, araya veritabani islemleri eklenerek kullanila da bilir fakat modellerle iliskili dosya yukleme islemleri icin bir sonraki baslikta anlatilanlar daha kullanislidir.
from django.shortcuts import render
from django.conf import settings
from django.core.files.storage import FileSystemStorage
def simple_upload(request):
if request.method == 'POST' and request.FILES['myfile']:
myfile = request.FILES['myfile']
fs = FileSystemStorage()
filename = fs.save(myfile.name, myfile)
uploaded_file_url = fs.url(filename)
return render(request, 'core/simple_upload.html', {
'uploaded_file_url': uploaded_file_url
})
return render(request, 'core/simple_upload.html')
File Upload With ModelForm
https://docs.djangoproject.com/en/2.2/topics/http/file-uploads/#handling-uploaded-files-with-a-model
Dosyanin validasyonunu ve kaydini FileSystemStorage() sinifini kullanmadan ModelForm’lar araciligiyla da yapabiliriz. Peki nasil?
models.py
from django.core.exceptions import ValidationError
import datetime
import os
import uuid
def content_file_name(instance, filename):
_datetime = datetime.datetime.now()
datetime_str = _datetime.strftime("%Y-%m-%d_%H-%M-%S")
ext = filename.split('.')[-1]
filename = "%s_%s.%s" % (datetime_str, uuid.uuid4(), ext)
return os.path.join('uploads/', filename)
def file_size(value):
limit = 2 * 1024 * 1024
if value.size > limit:
raise ValidationError('File too large. Size should not exceed 2 MiB.')
class MyModel(models.Model):
meta_data = models.CharField(max_length=500)
document = models.FileField(upload_to=content_file_name, blank=True, null=True, validators=[
file_size, FileExtensionValidator(allowed_extensions=['pdf', 'png', 'jpeg', 'jpg'])])
views.py
@api_view(['POST'])
@csrf_exempt
def upload_document(request):
try:
if request.method == 'POST' and request.FILES['document']:
form = ProposalForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save()
return Response({'status': 'ok'}, status=201)
else:
print(form.errors)
return Response(status=status.HTTP_400_BAD_REQUEST)
except KeyError:
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
forms.py
from django.forms import ModelForm, ModelChoiceField, widgets
from django import forms
from .models import *
class MyModelForm(ModelForm):
class Meta:
model = MyModel
exclude = ()
REQUEST
Yukaridaki yapi, ornek olarak verdigimiz istekten gelen dosyayi kaydedecek ve modeldeki alanlara karsilik gelen verileri veritabanina yazacaktir.
Burada sayan-i dikkat olan bir kac hususa dikkat cekmek istiyorum,
Goruldugu uzere , document isimli FileField tipindeki alanimiza validators ve upload_to isimli iki parametre gecilmis. validators icerisinde yuklenen dosyanin uzantisi ve boyutu olmak uzere 2 farkli validasyon yapiliyor. Eger yuklenmek istenen dosya bunlardan birisine uymazsa form.is_valid() ifadesi false donuyor yani dosyamiz upload olmuyor ve veritabani kaydi da yapilmiyor.
upload_to ifadesine karsilik gelen content_file_name fonksiyonu ise dosyaya benzersiz (unique) bir isim vermek icin kullandigim bir fonksiyon.
Bu parametereler zorunlu degil fakat ModelForm ile upload yaparken bu parametreleri kullanmak bana cok kullanisli geliyor.
Bir diger deginmek istedigim husus if request.method == ‘POST’ and request.FILES[‘document’]: satirinda gordugumuz request.FILES[‘document’] ifadesi. Burada parantez icerisindeki document ifadesi , istegi atarken dosyaya verdigimiz anahtar (key). Form validasyonunun yapilabilmesi icin bu anahtar ifadenin modelimizdeki dosyayi ifade alanla ayni ismi sahip olmasi gerekli. Yani modelimizdeki FileField ;
bir_mini_dosya = models.FileField(…)
seklinde tanimli ise, istekte dosyaya karsilik gelen anahtar da bir_mini_dosya olmali.
Kaynaklar
https://docs.djangoproject.com/en/2.2/topics/http/file-uploads/
https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html
https://docs.djangoproject.com/en/2.2/topics/http/file-uploads/#handling-uploaded-files-with-a-model
Leave a comment