How to use Django ImageField, and why use it at all?
<p>Up until now, I've been storing my image filenames in a CharField and saving the actual file directly to S3. This was a fine solution for my own usage. I'd like to reconsider using an ImageField, since now there will be other users and file input validation would be appropriate.</p>

<p>I have a couple of questions that weren't exactly answered after reading <a href="https://docs.djangoproject.com/en/1.9/ref/models/fields/#filefield" rel="noreferrer">the docs</a> and <a href="https://docs.djangoproject.com/en/1.9/_modules/django/db/models/fields/files/#FileField" rel="noreferrer">the source code</a> for FileField (which appears to be essentially ImageField minus the Pillow check and dimension field updating functionality).</p>

<p>1) Why use an ImageField at all? Or rather, why use a FileField? Sure, it's convenient for quick-and-easy forms and convenient for inserting to Django templates. But are there any substantial reasons, eg. Is it evidently secured against exploits and malicious uploads?</p>

<p>2) How to write to the field file? If it is correct that the file can be read by <code>instance.imagefield</code> (or is it <code>instance.imagefield.file</code>?), if I want to write to it can I simply do the following?</p>

<pre><code>@receiver(pre_save, sender=Image)
def pre_save_image(sender, instance, *args, **kwargs):
    instance.imagefield = process_image(instance.imagefield)
</code></pre>

<p>3) How to try saving with a specific filename, then try again with a new filename if that randomly generated filename already exists? For example with my code right now I do this, how can it be done with ImageField? I want to do it at the model layer, because if I do repeated tries at the view layer then the <code>pre_save</code> processing would run again which is ghetto (even though it's unlikely that it'll have a second try ever in the lifetime of the service).</p>

<pre><code>for i in range(tries):
    try:
        name = generate_random_name()
        media_storage.save(name + '.jpg', ContentFile(final_bytes))
        break
    except:
        pass
</code></pre>

<p>4) In the models.py <code>pre_save</code> and <code>post_save</code> signals and in the actual model's <code>save()</code>, how can I tell if a file came in with the request? i.e. I want to know if a new image is incoming to be saved, or if there is no image (some other field in the object is being updated and the image itself remains unchanged).</p>