Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass options to CloudinaryField in Django Model?

I am currently using Cloudinary with Django to store user profile pictures and would like to pass parameters to it store it in a folder and and overwrite the existing image instead of creating a new one.

In my user model:

picture = CloudinaryField('image')

This works as expected with Django Admin and forms. I would just like the ability to store it in the folder users/USERNAME/profile and when someone updates their picture to delete the old one.

like image 971
Alex Atwater Avatar asked Apr 23 '16 00:04

Alex Atwater


People also ask

How do I set up Cloudinary with Django?

To use the Cloudinary Django library, you have to configure at least your cloud_name. Your api_key and api_secret are also needed for secure API calls to Cloudinary (e.g., image and video uploads). You can find your account-specific configuration credentials in the Dashboard page of the account console.

How to use Django field choices?

How to use Django Field Choices ? Django Field Choices. According to documentation Field Choices are a sequence consisting itself of iterables of exactly two items (e.g. [ (A, B), (A, B) …]) to use as choices for some field. For example, consider a field semester which can have options as { 1, 2, 3, 4, 5, 6 } only.

Can a child class override a model field in Django?

In normal Python class inheritance, it is permissible for a child class to override any attribute from the parent class. In Django, this isn’t usually permitted for model fields.

Why can’t I create another model field called author in Django?

In Django, this isn’t usually permitted for model fields. If a non-abstract model base class has a field called author, you can’t create another model field or define an attribute called author in any class that inherits from that base class. This restriction doesn’t apply to model fields inherited from an abstract model.


3 Answers

update

The solution that worked in 2016 is no longer viable. According to the docs, the following will work:

image = CloudinaryField(
    "Image",
    overwrite=True,
    resource_type="image",
    transformation={"quality": "auto:eco"},
    format="jpg",
)

The allowed params are listed here and here in the code for version 1.17.0 or here in the docs.

For example, I was confused with the keyword quality. I was using it directly when using the API but in CloudinaryField is not allowed.

The proper way to define the quality of the uploaded photo is by setting:

transformation={"quality": 80}.

This is clarified in the docs where it is explained that:

Note that when using the SDK for a dynamically typed language, the transformation parameters can be specified directly without using this transformation parameter.


This worked perfectly:

from cloudinary.models import CloudinaryField as BaseCloudinaryField
from django.db import models


class CloudinaryField(BaseCloudinaryField):
    def upload_options(self, model_instance):
        return {
            'public_id': model_instance.name,
            'unique_filename': False,
            'overwrite': True,
            'resource_type': 'image',
            'tags': ['map', 'market-map'],
            'invalidate': True,
            'quality': 'auto:eco',
        }

class MarketMap(models.Model):
    name = models.CharField(max_length=17)
    image = CloudinaryField()
like image 141
raratiru Avatar answered Oct 16 '22 10:10

raratiru


You can also add these kind of options to the form field like so:

image = CloudinaryFileField(
    label='My image',
    options={
        'tags': "module, home",
        'format': 'jpg',
        'crop': 'limit',
        'width': 640
    },
    required=False)
like image 32
Christoffer Avatar answered Oct 16 '22 10:10

Christoffer


It took me a while to realize -- and based on the questions I see in StackOverflow its not clear for others as well -- CloudinaryField and CloudinaryFileField appear similar but are different classes. CloudinaryField is a Model class, whereas CloudinaryFileField is a Form class. The options to specify a file path or tags are done at the FORM level with CloudinaryFileField (See Image Upload API documentation)

from cloudinary.forms import CloudinaryFileField
# Note - cloudinary folders are specified at the FORM level and not in the MODEL
class EditPhotoForm(ModelForm):
class Meta:
    model = Photo
    fields = ('name', 'description', 'image', 'slug')
    image = CloudinaryFileField(options={'folder' : 'media/photos/', 'tags': 'landscapes'})
like image 1
Philip Avatar answered Oct 16 '22 12:10

Philip