#32243: Clarify docs on manually setting and saving a FileField.
-------------------------------------+-------------------------------------
     Reporter:  Gordon Wrigley       |                    Owner:  Hasanul
         Type:                       |  Islam
  Cleanup/optimization               |                   Status:  assigned
    Component:  Documentation        |                  Version:  3.1
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Jesse):

 Replying to [comment:5 Hasanul Islam]:
 > Hi Carlton,
 > As the file is not being saved without the `name` attribute of the file,
 shouldn't we generate the `name` property randomly if not provided by the
 user?
 >
 > If yes, I will update the relevant codes implementing random name
 generation, otherwise, I will update the documentation mentioning `name`
 is required. However, I think we should not enforce the user to provide
 the `name` attribute. I would prefer to update the code.
 **TL;DR:** Allow ContentFiles with a blank/None name. In
 `FileField.save()`, add a check after the `generate_filename()` call to
 make sure the file actually has a name once we're ready to save it to
 disk.

 When saving the model it seems to still use the `upload_to` argument. If
 you pass something for `upload_to` it will overwrite whatever was passed
 for `name`.

 Here's an example of my use case. A user can upload a picture through the
 admin panel. Whenever a new picture is uploaded I create a thumbnail for
 it.

 {{{
 def photo_upload_path(instance, original_filename):
     filename =
 hashlib.sha256(str(time.time()).encode("utf-8")).hexdigest()
     filename = filename[:16]
     return f"photos/{filename}.jpg"


 def thumbnail_upload_path(instance, original_filename):
     filename = os.path.basename(instance.photo.name)
     return f"photos/thumbnails/{filename}"


 class MyModel(models.Model):
     photo = models.ImageField(upload_to=photo_upload_path)

     # Hidden in Django admin. Managed by us.
     photo_thumbnail = models.ImageField(upload_to=thumbnail_upload_path)

     def save(self):
         img = Image.open(self.photo.path)
         img.thumbnail(settings.THUMBNAIL_SIZE)

         contents = io.BytesIO()
         img.save(contents, "JPEG")

         self.photo_thumbnail = ContentFile(contents.getvalue(),
 name="foo")

         super.save()
 }}}


 In this case, the photo gets renamed to `photos/<hash>.jpg`, and I want
 thumbnails to go to `photos/thumbnails/<hash>.jpg`.

 I resize the image, save its contents to a BytesIO object, and create the
 ContentFile object. However I have to pass in a bogus name for the
 ContentFile even though it will use the `upload_to` to overwrite it. If I
 pass an empty name Django seems to throw the file away and it doesn't get
 saved.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/32243#comment:6>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/065.79004614098234381290f1ffb0eab36f%40djangoproject.com.

Reply via email to