0
# Django Integration
1
2
Complete Django framework integration including model fields, form widgets, template tags, and admin interface components.
3
4
## Capabilities
5
6
### Model Fields
7
8
Django model field for storing Cloudinary resource references.
9
10
```python { .api }
11
class CloudinaryField(models.Field):
12
"""Django model field for Cloudinary resources.
13
14
Stores Cloudinary resource information as a JSON-serializable format and
15
provides easy access to resource URLs and transformations.
16
"""
17
18
def __init__(self, type="upload", resource_type="image", **options):
19
"""Initialize CloudinaryField.
20
21
Args:
22
type (str, optional): Delivery type ('upload', 'private', 'authenticated')
23
resource_type (str, optional): Resource type ('image', 'video', 'raw', 'auto')
24
**options: Additional field options
25
"""
26
27
def get_internal_type(self):
28
"""Get the internal field type for Django."""
29
30
def to_python(self, value):
31
"""Convert database value to Python CloudinaryResource object.
32
33
Args:
34
value: Database value (string, dict, or CloudinaryResource)
35
36
Returns:
37
CloudinaryResource: Cloudinary resource object or None
38
"""
39
40
def from_db_value(self, value, expression, connection):
41
"""Convert database value to Python object."""
42
43
def get_prep_value(self, value):
44
"""Convert Python value to database-storable format."""
45
46
def value_to_string(self, obj):
47
"""Convert field value to string representation."""
48
49
def formfield(self, **kwargs):
50
"""Return appropriate form field for this model field."""
51
```
52
53
### Form Fields and Widgets
54
55
Django form components for handling Cloudinary uploads.
56
57
```python { .api }
58
class CloudinaryInput(forms.TextInput):
59
"""Text input widget for Cloudinary resource public IDs.
60
61
Provides a simple text input for entering Cloudinary public IDs manually.
62
"""
63
64
def __init__(self, attrs=None):
65
"""Initialize the input widget.
66
67
Args:
68
attrs (dict, optional): HTML attributes for the input element
69
"""
70
71
class CloudinaryFileField(forms.FileField):
72
"""File field that uploads to Cloudinary on form submission.
73
74
Handles file uploads to Cloudinary and returns the uploaded resource information.
75
"""
76
77
def __init__(self, **options):
78
"""Initialize the file field.
79
80
Args:
81
**options: Cloudinary upload options (same as uploader.upload())
82
"""
83
84
def to_python(self, data):
85
"""Process uploaded file and upload to Cloudinary."""
86
87
class CloudinaryJsFileField(forms.Field):
88
"""JavaScript-based file field for direct browser uploads.
89
90
Uses Cloudinary's JavaScript upload widget for direct browser-to-Cloudinary uploads
91
without going through your server.
92
"""
93
94
def __init__(self, **options):
95
"""Initialize the JavaScript file field.
96
97
Args:
98
**options: Upload widget configuration options
99
"""
100
101
class CloudinaryUnsignedJsFileField(CloudinaryJsFileField):
102
"""JavaScript file field for unsigned uploads using upload presets.
103
104
Allows uploads without server-side signature generation using predefined upload presets.
105
"""
106
107
def __init__(self, upload_preset, **options):
108
"""Initialize the unsigned JavaScript file field.
109
110
Args:
111
upload_preset (str): Name of the upload preset to use
112
**options: Additional upload widget options
113
"""
114
```
115
116
### Template Tags
117
118
Django template tags for generating Cloudinary URLs and HTML elements.
119
120
```python { .api }
121
def cloudinary_url(public_id, **options):
122
"""Template tag for generating Cloudinary URLs.
123
124
Usage in templates:
125
{% load cloudinary %}
126
{% cloudinary_url "sample" width=300 height=200 crop="fill" %}
127
128
Args:
129
public_id (str): Public ID of the resource
130
**options: Transformation and URL generation options
131
132
Returns:
133
str: Generated Cloudinary URL
134
"""
135
136
def cloudinary_tag(public_id, **options):
137
"""Template tag for generating Cloudinary image tags.
138
139
Usage in templates:
140
{% load cloudinary %}
141
{% cloudinary_tag "sample" width=300 height=200 crop="fill" alt="Sample" %}
142
143
Args:
144
public_id (str): Public ID of the resource
145
**options: Transformation options and HTML attributes
146
147
Returns:
148
str: HTML img tag with Cloudinary URL
149
"""
150
151
def cloudinary_direct_upload_field(form_field, **options):
152
"""Template tag for direct upload fields.
153
154
Usage in templates:
155
{% cloudinary_direct_upload_field form.image %}
156
157
Args:
158
form_field: Django form field instance
159
**options: Upload widget options
160
161
Returns:
162
str: HTML for direct upload widget
163
"""
164
165
def cloudinary_includes():
166
"""Template tag for including Cloudinary JavaScript files.
167
168
Usage in templates:
169
{% cloudinary_includes %}
170
171
Returns:
172
str: HTML script tags for Cloudinary JavaScript
173
"""
174
175
def cloudinary_js_config():
176
"""Template tag for JavaScript configuration.
177
178
Usage in templates:
179
{% cloudinary_js_config %}
180
181
Returns:
182
str: JavaScript configuration object
183
"""
184
185
def cloudinary_direct_upload(callback_url=None, **options):
186
"""Template tag for direct upload configuration.
187
188
Usage in templates:
189
{% cloudinary_direct_upload callback_url="/upload_complete/" %}
190
191
Args:
192
callback_url (str, optional): URL to call after upload completion
193
**options: Upload configuration options
194
195
Returns:
196
str: JavaScript for direct upload setup
197
"""
198
```
199
200
### Form Initialization
201
202
Helper functions for setting up forms with Cloudinary integration.
203
204
```python { .api }
205
def cl_init_js_callbacks(form, request):
206
"""Initialize JavaScript callbacks for Cloudinary forms.
207
208
Args:
209
form: Django form instance
210
request: Django request object
211
212
Returns:
213
str: JavaScript initialization code
214
"""
215
```
216
217
## Usage Examples
218
219
### Model Definition
220
221
```python
222
from django.db import models
223
from cloudinary.models import CloudinaryField
224
225
class Product(models.Model):
226
"""Product model with Cloudinary image fields."""
227
228
name = models.CharField(max_length=100)
229
description = models.TextField()
230
231
# Single image field
232
image = CloudinaryField('image', null=True, blank=True)
233
234
# Video field
235
video = CloudinaryField('video', resource_type='video', null=True, blank=True)
236
237
# Private image field
238
private_image = CloudinaryField('image', type='private', null=True, blank=True)
239
240
# Raw file field
241
document = CloudinaryField('raw', resource_type='raw', null=True, blank=True)
242
243
def __str__(self):
244
return self.name
245
246
def get_image_url(self, **options):
247
"""Get transformed image URL."""
248
if self.image:
249
return self.image.build_url(**options)
250
return None
251
252
def get_thumbnail_url(self):
253
"""Get thumbnail URL."""
254
return self.get_image_url(
255
width=300,
256
height=300,
257
crop="fill",
258
quality="auto"
259
)
260
261
# Usage in views
262
def product_detail(request, product_id):
263
product = Product.objects.get(id=product_id)
264
265
# Access Cloudinary resource
266
if product.image:
267
image_url = product.image.build_url(width=800, height=600, crop="fit")
268
thumbnail_url = product.image.build_url(width=200, height=200, crop="thumb")
269
270
return render(request, 'product_detail.html', {
271
'product': product,
272
'image_url': image_url,
273
'thumbnail_url': thumbnail_url
274
})
275
```
276
277
### Form Definition
278
279
```python
280
from django import forms
281
from cloudinary.forms import CloudinaryFileField, CloudinaryJsFileField, CloudinaryUnsignedJsFileField
282
from .models import Product
283
284
class ProductForm(forms.ModelForm):
285
"""Form for creating/editing products with Cloudinary uploads."""
286
287
class Meta:
288
model = Product
289
fields = ['name', 'description', 'image', 'video']
290
291
# Override with Cloudinary file field
292
image = CloudinaryFileField(
293
options={
294
'tags': 'product_image',
295
'folder': 'products',
296
'transformation': [
297
{'width': 1000, 'height': 1000, 'crop': 'limit'},
298
{'quality': 'auto', 'format': 'auto'}
299
],
300
'eager': [
301
{'width': 300, 'height': 300, 'crop': 'thumb'},
302
{'width': 800, 'height': 600, 'crop': 'fit'}
303
]
304
}
305
)
306
307
class ProductJsForm(forms.ModelForm):
308
"""Form using JavaScript-based direct uploads."""
309
310
class Meta:
311
model = Product
312
fields = ['name', 'description', 'image']
313
314
# JavaScript upload field
315
image = CloudinaryJsFileField(
316
options={
317
'tags': 'js_upload',
318
'folder': 'products',
319
'resource_type': 'image',
320
'format': 'auto',
321
'quality': 'auto'
322
}
323
)
324
325
class ProductUnsignedForm(forms.ModelForm):
326
"""Form using unsigned uploads with preset."""
327
328
class Meta:
329
model = Product
330
fields = ['name', 'description', 'image']
331
332
# Unsigned upload field
333
image = CloudinaryUnsignedJsFileField(
334
'product_preset', # Upload preset name
335
options={
336
'tags': 'unsigned_upload',
337
'folder': 'products'
338
}
339
)
340
```
341
342
### Template Usage
343
344
```html
345
<!-- Load Cloudinary template tags -->
346
{% load cloudinary %}
347
348
<!-- Include Cloudinary JavaScript (required for JS uploads) -->
349
{% cloudinary_includes %}
350
351
<!-- Display image with transformations -->
352
{% if product.image %}
353
{% cloudinary_tag product.image.public_id width=400 height=300 crop="fill" alt=product.name class="img-responsive" %}
354
{% endif %}
355
356
<!-- Generate URL only -->
357
{% cloudinary_url product.image.public_id width=800 height=600 crop="fit" as large_image_url %}
358
<a href="{{ large_image_url }}" target="_blank">View Large Image</a>
359
360
<!-- Form with direct upload -->
361
<form method="post" enctype="multipart/form-data">
362
{% csrf_token %}
363
364
{{ form.name.label_tag }}
365
{{ form.name }}
366
367
{{ form.description.label_tag }}
368
{{ form.description }}
369
370
<!-- Direct upload field -->
371
{% cloudinary_direct_upload_field form.image %}
372
373
<button type="submit">Save Product</button>
374
</form>
375
376
<!-- JavaScript configuration -->
377
{% cloudinary_js_config %}
378
379
<!-- Responsive image with breakpoints -->
380
{% cloudinary_tag product.image.public_id width=800 height=600 crop="fill" responsive=True class="img-responsive" %}
381
```
382
383
### Advanced Template Examples
384
385
```html
386
<!-- Conditional image display -->
387
{% if product.image %}
388
<div class="product-image">
389
{% cloudinary_tag product.image.public_id width=500 height=400 crop="fill" quality="auto" format="auto" alt=product.name %}
390
391
<!-- Thumbnail gallery -->
392
<div class="thumbnails">
393
{% cloudinary_tag product.image.public_id width=100 height=100 crop="thumb" %}
394
{% cloudinary_tag product.image.public_id width=100 height=100 crop="thumb" effect="sepia" %}
395
{% cloudinary_tag product.image.public_id width=100 height=100 crop="thumb" effect="grayscale" %}
396
</div>
397
</div>
398
{% else %}
399
<div class="no-image">
400
<p>No image available</p>
401
</div>
402
{% endif %}
403
404
<!-- Video with poster image -->
405
{% if product.video %}
406
<video controls width="640" height="480"
407
poster="{% cloudinary_url product.video.public_id resource_type='video' format='jpg' %}">
408
<source src="{% cloudinary_url product.video.public_id resource_type='video' format='mp4' %}" type="video/mp4">
409
<source src="{% cloudinary_url product.video.public_id resource_type='video' format='webm' %}" type="video/webm">
410
</video>
411
{% endif %}
412
```
413
414
### View Integration
415
416
```python
417
from django.shortcuts import render, redirect
418
from django.contrib import messages
419
from .forms import ProductForm, ProductJsForm
420
from .models import Product
421
422
def create_product(request):
423
"""Create product with Cloudinary upload."""
424
425
if request.method == 'POST':
426
form = ProductForm(request.POST, request.FILES)
427
if form.is_valid():
428
product = form.save()
429
430
# Access uploaded image information
431
if product.image:
432
print(f"Uploaded image: {product.image.public_id}")
433
print(f"Image URL: {product.image.url}")
434
print(f"Secure URL: {product.image.build_url(secure=True)}")
435
436
messages.success(request, 'Product created successfully!')
437
return redirect('product_detail', product_id=product.id)
438
else:
439
form = ProductForm()
440
441
return render(request, 'create_product.html', {'form': form})
442
443
def product_gallery(request):
444
"""Display product gallery with various transformations."""
445
446
products = Product.objects.filter(image__isnull=False)
447
448
# Prepare image variations
449
product_images = []
450
for product in products:
451
if product.image:
452
product_images.append({
453
'product': product,
454
'thumbnail': product.image.build_url(width=200, height=200, crop="thumb"),
455
'medium': product.image.build_url(width=400, height=300, crop="fill"),
456
'large': product.image.build_url(width=800, height=600, crop="fit"),
457
})
458
459
return render(request, 'product_gallery.html', {
460
'product_images': product_images
461
})
462
```
463
464
### Django Settings Configuration
465
466
```python
467
# settings.py
468
import cloudinary
469
470
# Cloudinary configuration
471
cloudinary.config(
472
cloud_name="your_cloud_name",
473
api_key="your_api_key",
474
api_secret="your_api_secret",
475
secure=True
476
)
477
478
# Optional: Default upload parameters
479
CLOUDINARY_STORAGE = {
480
'CLOUD_NAME': 'your_cloud_name',
481
'API_KEY': 'your_api_key',
482
'API_SECRET': 'your_api_secret'
483
}
484
485
# Template context processors (if using template tags)
486
TEMPLATES = [
487
{
488
'BACKEND': 'django.template.backends.django.DjangoTemplates',
489
'DIRS': [],
490
'APP_DIRS': True,
491
'OPTIONS': {
492
'context_processors': [
493
'django.template.context_processors.debug',
494
'django.template.context_processors.request',
495
'django.contrib.auth.context_processors.auth',
496
'django.contrib.messages.context_processors.messages',
497
],
498
},
499
},
500
]
501
502
# Add cloudinary to INSTALLED_APPS
503
INSTALLED_APPS = [
504
'django.contrib.admin',
505
'django.contrib.auth',
506
'django.contrib.contenttypes',
507
'django.contrib.sessions',
508
'django.contrib.messages',
509
'django.contrib.staticfiles',
510
'cloudinary',
511
'your_app',
512
]
513
```