77

I'm writing a simple real-estate listing app in Django. Each property needs to have a variable number of images. Images need to have an editable order. And I need to make the admin user-proof.

So that said, what are my options?

  1. Is there a ImageList field that I don't know about?

  2. Is there an app like django.contrib.comments that does the job for me?

  3. If I have to write it myself, how would I go about making the admin-side decent? I'm imagining something a lot slicker than what ImageField provides, with some drag'n'drop for re-ordering. But I'm a complete clutz at writing admin pages =(

Oli
  • 235,628
  • 64
  • 220
  • 299

4 Answers4

144
  1. Variable lists, also known as a many-to-one relationship, are usually handled by making a separate model for the many and, in that model, using a ForeignKey to the "one".

  2. There isn't an app like this in django.contrib, but there are several external projects you can use, e.g. django-photologue which even has some support for viewing the images in the admin.

  3. The admin site can't be made "user proof", it should only be used by trusted users. Given this, the way to make your admin site decent would be to define a ModelAdmin for your property and then inline the photos (inline documentation).

So, to give you some quick drafts, everything would look something like this:

# models.py
class Property(models.Model):
    address = models.TextField()
    ...

class PropertyImage(models.Model):
    property = models.ForeignKey(Property, related_name='images')
    image = models.ImageField()

and:

# admin.py
class PropertyImageInline(admin.TabularInline):
    model = PropertyImage
    extra = 3

class PropertyAdmin(admin.ModelAdmin):
    inlines = [ PropertyImageInline, ]

admin.site.register(Property, PropertyAdmin)

The reason for using the related_name argument on the ForeignKey is so your queries will be more readable, e.g. in this case you can do something like this in your view:

property = Property.objects.get(pk=1)
image_list = property.images.all()

EDIT: forgot to mention, you can then implement drag-and-drop ordering in the admin using Simon Willison's snippet Orderable inlines using drag and drop with jQuery UI

Qback
  • 4,310
  • 3
  • 25
  • 38
Van Gale
  • 43,536
  • 9
  • 71
  • 81
  • 1
    The PropertyImage model should include a field for ordering. – akaihola Feb 12 '09 at 10:11
  • 1
    Thanks, amazing! The orderable snippet works great, after a slight change, as it isn't written for FileFields. Line 59 needs to become "if ($(this).find('input[type=file]').val() || $(this).find('p.file-upload').length) {" to check if it either already has a file uploaded, or has a file pending upload. Also, it works on a StackedInline, not a TabularInline (out of the box, anyway). – mrooney Aug 29 '12 at 22:46
  • how delete it images from admin? – Nikita Davidenko May 05 '17 at 17:04
  • 1
    Thank you very much for your contribution! How would you handle your forms in the views? How to "inline" the photos in the view in order for a user to upload an image when he is adding or updating a property? – Redjam Mar 18 '19 at 19:08
7

Write an Image model that has a ForeignKey to your Property model. Quite probably, you'll have some other fields that belong to the image and not to the Property.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Javier
  • 60,510
  • 8
  • 78
  • 126
4

I'm currently making the same thing and I faced the same issue.

After I researched for a while, I decided to use django-imaging. It has a nice Ajax feature, images can be uploaded on the same page as the model Insert page, and can be editable. However, it is lacking support for non-JPEG extension.

John R Perry
  • 3,916
  • 2
  • 38
  • 62
Adrian Liem
  • 251
  • 1
  • 3
  • 11
0

There is a package named django-galleryfield. I think it will meet your demand.

Dzhuang
  • 1,895
  • 1
  • 14
  • 15