Herramientas de usuario

Herramientas del sitio


wiki2:python:django:others

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
wiki2:python:django:others [2020/10/09 15:13]
alfred [Upload files]
wiki2:python:django:others [2020/10/31 20:16] (actual)
Línea 27: Línea 27:
 # Delete a session value  # Delete a session value 
 del request.session['​my_car'​] del request.session['​my_car'​]
 +</​code>​
 +
 +
 +===== Sending mails =====
 +You can send mails with:
 +<​code>​
 +from django.core.mail import send_mail
 +send_mail('​subject',​ '​message',​ 'Dont Reply <​do_not_reply@domain.com>',​ ['​youremail@example.com'​])
 </​code>​ </​code>​
  
Línea 87: Línea 95:
   * ''​FILE_UPLOAD_PERMISSIONS''​   * ''​FILE_UPLOAD_PERMISSIONS''​
   * ''​FILE_UPLOAD_TEMP_DIR'':​ Directory to store files larger than ''​FILE_UPLOAD_MAX_MEMORY_SIZE''​ value.   * ''​FILE_UPLOAD_TEMP_DIR'':​ Directory to store files larger than ''​FILE_UPLOAD_MAX_MEMORY_SIZE''​ value.
-  * ''​MEDIA_ROOT''​ +  * ''​MEDIA_ROOT''​: Absolute filesystem path to the directory that will hold user-uploaded files. 
-  * ''​MEDIA_URL''​+  * ''​MEDIA_URL''​: URL that handles the media served from MEDIA_ROOT, used for managing stored files. It must end in a slash.
  
  
Línea 97: Línea 105:
 Sometimes particular views require **different upload behavior**. In these cases, you can override upload handlers on a per-request basis by modifying ''​request.upload_handlers''​. Sometimes particular views require **different upload behavior**. In these cases, you can override upload handlers on a per-request basis by modifying ''​request.upload_handlers''​.
  
 +By default Django stores files locally, using the MEDIA_ROOT and MEDIA_URL settings. ​
  
 +When you use a FileField or ImageField, Django provides a set of APIs you can use to deal with that file.
 +
 +<code python>
 +class Car(models.Model):​
 +    name = models.CharField(max_length=255)
 +    price = models.DecimalField(max_digits=5,​ decimal_places=2)
 +    photo = models.ImageField(upload_to='​cars'​)
 +
 +car = Car.objects.get(name="​57 Chevy"​)
 +car.photo
 +# <​ImageFieldFile:​ cars/​chevy.jpg>​
 +car.photo.name
 +# '​cars/​chevy.jpg'​
 +car.photo.path
 +# '/​media/​cars/​chevy.jpg'​
 +car.photo.url
 +# '​http://​media.example.com/​cars/​chevy.jpg'​
 +</​code>​
 +
 +You can change the path in this way:
 +<code python>
 +>>>​ import os
 +>>>​ from django.conf import settings
 +>>>​ initial_path = car.photo.path
 +>>>​ car.photo.name = '​cars/​chevy_ii.jpg'​
 +>>>​ new_path = settings.MEDIA_ROOT + car.photo.name
 +>>>​ # Move the file on the filesystem
 +>>>​ os.rename(initial_path,​ new_path)
 +>>>​ car.save()
 +>>>​ car.photo.path
 +'/​media/​cars/​chevy_ii.jpg'​
 +>>>​ car.photo.path == new_path
 +True
 +</​code>​
 +
 +To manipulate images:
 +<code python>
 +>>>​ from PIL import Image
 +>>>​ car = Car.objects.get(name='​57 Chevy'​)
 +>>>​ car.photo.width
 +191
 +>>>​ car.photo.height
 +287
 +>>>​ image = Image.open(car.photo)
 +# Raises ValueError: seek of closed file.
 +>>>​ car.photo.open()
 +<​ImageFieldFile:​ cars/​chevy.jpg>​
 +>>>​ image = Image.open(car.photo)
 +>>>​ image
 +<​PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=191x287 at 0x7F99A94E9048>​
 +</​code>​
 +
 +Django delegates decisions about how and where to store files to a file **storage system**. This is the object that actually understands things like file systems, opening and reading files, etc. The default file storage is given by the ''​DEFAULT_FILE_STORAGE''​ setting.
 +
 +You can write your [[https://​docs.djangoproject.com/​en/​3.1/​howto/​custom-file-storage/​|own file storage]].
 +
 +You can create an instance of some custom file storage class, or – often more useful – you can use the global default storage system:
 +<​code>​
 +>>>​ from django.core.files.base import ContentFile
 +>>>​ from django.core.files.storage import default_storage
 +>>>​ path = default_storage.save('​path/​to/​file',​ ContentFile(b'​new content'​))
 +>>>​ path
 +'​path/​to/​file'​
 +>>>​ default_storage.size(path)
 +11
 +>>>​ default_storage.open(path).read()
 +b'new content'​
 +>>>​ default_storage.delete(path)
 +>>>​ default_storage.exists(path)
 +False
 +</​code>​
 +
 +The following code will store uploaded files under /​media/​photos regardless of what your MEDIA_ROOT setting is:
 +<code python>
 +from django.core.files.storage import FileSystemStorage
 +from django.db import models
 +
 +fs = FileSystemStorage(location='/​media/​photos'​)
 +
 +class Car(models.Model):​
 +    ...
 +    photo = models.ImageField(storage=fs)
 +</​code>​
 +
 +You can use a callable as the storage parameter for FileField or ImageField. This allows you to modify the used storage at runtime, selecting different storages for different environments,​ for example:
 +<code python>
 +def select_storage():​
 +    return MyLocalStorage() if settings.DEBUG else MyRemoteStorage()
 +
 +class MyModel(models.Model):​
 +    my_file = models.FileField(storage=select_storage)
 +</​code>​
 +
 +==== For using S3 or an alterantive service ====
 +
 +You need the ''​boto3''​ and ''​django-storages''​ packages.
 +
 +An example of settings would be...
 +<​code>​
 +AWS_ACCESS_KEY_ID = ''​
 +AWS_SECRET_ACCESS_KEY = ''​
 +AWS_STORAGE_BUCKET_NAME = '​codi.coop.test'​
 +AWS_S3_CUSTOM_DOMAIN = f'​s3.wasabisys.com/​{AWS_STORAGE_BUCKET_NAME}'​
 +AWS_S3_ENDPOINT_URL = '​https://​s3.wasabisys.com'​
 +AWS_DEFAULT_ACL = '​public-read'​
 +DEFAULT_FILE_STORAGE = '​cc_lib.storages.MediaStorage'​
 +EXTERNAL_MEDIA_PATH = '​fok/​media'​
 +MEDIA_FILE_OVERWRITE = True
 +# AWS_S3_OBJECT_PARAMETERS = {'​CacheControl':​ '​max-age=86400',​}
 +</​code>​
 +
 +Being the ''​cc_lib.storages.MediaStorage''​ the next:
 +<code python>
 +from storages.backends.s3boto3 import S3Boto3Storage
 +from django.conf import settings
 +
 +
 +class MediaStorage(S3Boto3Storage):​
 +    location = settings.EXTERNAL_MEDIA_PATH
 +    file_overwrite = settings.MEDIA_FILE_OVERWRITE
 +</​code>​
 +
 +With this you could create other storages like ''​PrivateMediaStorage''​ and use it like this:
 +<code python>
 +class Document(models.Model):​
 +    uploaded_at = models.DateTimeField(auto_now_add=True)
 +    upload = models.FileField()
 +
 +
 +class PrivateDocument(models.Model):​
 +    uploaded_at = models.DateTimeField(auto_now_add=True)
 +    upload = models.FileField(storage=PrivateMediaStorage())
 +    user = models.ForeignKey(User,​ related_name='​documents'​)
 +</​code>​
 +
 +==== So... ====
 +
 +  - Install boto3 and django-storages.
 +  - Create your own MediaStorage.
 +  - Add the settings.
 +  - Configure models.
 +  - Remind that forms in template must have the attribute ''​enctype=“multipart/​form-data”''​.
 +
 +
 +==== Notes ====
 +<code python>
 +def upload_path(instance,​ filename):
 +    if instance.type == Resource.ResourceType.PROFILE_PICTURE.value:​
 +        return f'​authors/​{instance.owner.uuid}/​avatars/​{instance.uuid}.png'​
 +    elif instance.type == Resource.ResourceType.ZINE_COVER.value:​
 +        return f'​zines/​{str(instance.related_to)}/​cover.jpg'​
 +</​code>​
wiki2/python/django/others.1602256431.txt.gz · Última modificación: 2020/10/09 16:13 (editor externo)