I am designing a website using django. The idea of a website is to have photographers and each photographer would have an album or more albums and each album would have one or more photo/photos. Currently I have:
class Photo(models.Model):
name=models.ForeignKey('Album')
p=models.ImageField()
def __unicode__(self):
return self.name
class Album(models.Model):
name=models.ForeignKey('Photographer')
def __unicode__(self):
return self.name
class Photographer(models.Model):
name=models.ForeignKey('User')
def __unicode__(self):
return self.name
The question is if you have the same design would you create a directory for each photographer and for each album you would create another directory in the parent directory and then store the photos in that album's directory or store them in the database. I know that is a newbie question but I really need help. If you have other design to make it easier on me please let me know.
Thanks in advance,
Abdul
Use the imagefield to store all the photos at one place and even better store them in cloud storage services. And as to regarding the relation have ForeignKeys in Photo model relating to Album and Photographer. Than use reverse relationship to find out the photos of each album or Photographer.
Your code might look like this`
class Photo(models.Model):
image = ImageField(upload_to="whereever you want to")
album = ForeignKey(Album)
photographer=ForeignKey(Photographer)
and after you get a particular album you can use
Album.set_all and photographer.set_all to get all the photos of a particular album or photographer
`
Yes, store the photos directly in the file system, rather than database. This is a common practise which makes sense for many reasons, mostly related to performance.
If you expect to have thousends of photos then dont keep them one directory, cause that can cause performance issues on popular systems. Instead, design a simple hierarchy appropriate for your application.
There is no need to create directories for photographer or an album. That is what databases are for. You can have one giant folder (specified in upload_to) which will contain all uploaded images for all photographers and albums and then its up for a db to keep track which photos belong to what photographer/album.
By the way you should specify upload_to parameter for ImageField:
models.ImageField(upload_to='images/')
If you really want to create folders for each album, you can pass a function to upload_to parameter and add whatever logic you want there... more about that in the docs here.
Related
Currently building backend API using Django Rest Framework for a group photo-sharing project.
I'm trying to understand what's the best way to structure my API endpoints and I've encountered a problem (more like a question) for the best way to implement it.
Here are my models:
class Photo(models.Model):
uploader = models.ForeignKey(
CustomUser, on_delete=models.CASCADE, related_name="photos"
)
image = models.ImageField(upload_to=get_image_path)
upload_date = models.DateField(auto_now_add=True, editable=False)
class Collection(models.Model):
name = models.CharField(max_length=255)
description = models.CharField(max_length=500, blank=True)
thumbnail = models.ImageField(blank=True)
creator = models.ForeignKey(
CustomUser, on_delete=models.CASCADE, related_name="created_collections"
)
members = models.ManyToManyField(CustomUser, related_name="collections")
photos = models.ManyToManyField(Photo, related_name="collections")
Basically each user can create a Collection model which holds different photos he can share with others and they can upload too.
The endpoints I have right now are the basic ViewSet ones:
Photo:
/api/photo GET/POST
/api/photo/id GET/DELETE/PATCH
Collection:
/api/collection GET/POST
/api/collection/id GET/DELETE/PATCH
My question is:
What should be the endpoint for a user to add a photo to a collection? (the best way to implement it)
I've thought of a few options which are:
1.POST request to /api/collection/id containing the ID of the photo I want to add.
2.POST request to /api/photo/id containing the ID of the collection I want to add the photo to.
3.Using a PATCH method maybe? (Don't know if that would be better)
I am trying to understand what would be the best REST practice in this case.
Let me know if you need to see more code,
Thanks!
Link to the git: https://github.com/davidplo4545/JustShare.git
This stackoverflow blog post is a great explanation of REST best practices, specifically the section 'Use nouns instead of verbs in endpoint paths'.
Accordingly, your endpoints would look like this:
GET /api/photos/ to retrieve a list of photos
POST /api/photos/ to create a photo
PUT /api/photos/:id to update a photo with the given ID
DELETE /api/photos/:id to delete a photo with the given ID
This would be the same for collections, so to add an existing photo to a collection you would make a PUT request to api/collections/:id and update the photos field. The syntax of this request is up to your individual implementation.
I am working on an application that has a record of movies and actors. I actors to have a lot of images and/or a lot of videos which should have the user's or movie id as part of the file path. I have decided to use a m2m relationship since the image or video file could belong to either a person or a movie but I'm stuck cause I'm not sure of how to approach this problem. Here is a sample of my image class. The video class is more or less the same.
class Image(models.Model):
title = models.CharField(max_length=128)
photo = models.ImageField(upload_to=file_path)
actors = models.ManyToManyField(
'Actor',
related_name='images'
)
movies= models.ManyToManyField(
'Movie',
related_name='images',
)
But this way I have no way of storing actor or movie id as part of the file path
I thought of using a ForeignKey relationship instead of a m2m relationship but I thought that would not be accurate as not all Image objects would have an actor and Movie associated to it. I believe the relationship would be an either or relationship. Is there another way I could approach this problem?
I'm building a django app that has an image gallery, and the client insists the images be displayed in specific order. I use the admin interface to upload the images and edit their properties, and I have an ImageFile class in my model that basically looks like this:
class ImageFile(models.Model):
"""represents an image file"""
# the image description
description = models.CharField(max_length=45)
# the actual image
image = models.ImageFile(upload_to='images')
# running number representing the order on the page
order = models.IntegerField()
def __unicode__(self):
return "%s" % (self.description)
class Meta:
db_table = 'images'
I'm using the IntegerField 'order' to have running number that'll control the sorting. I figured there has to be a smarter/better way to do this (another model?) and also be able to easily control it through the admin interface.
I suppouse you would like give possibility to sort images to user, (anyway if you want sort it via time add, best way is order it by id), so, if there is model like Gallery (of images) maybe you should store tuple of ids of images from the galery (in DB as a text object). After read cast it to tuple, and you have expected order. Hope I help.
if the order of the images is the order that they are uploaded you could use a timestamp to order them,.
I used the same method (with integer "order" field in the model) to define the ordering. However, I customized the admin to allow drag and drop the images belong to an album to define the order. When the admin hits "save" button, the order will be calculated automatically based on the current order after drag-and-drop. All data will be submitted to the server for saving to DB.
I'm building a site for a client that needs to support image uploads (an artist) through the admin interface. Since most of the images are pretty high-res, I wanted to create thumb copies of the image to display on the gallery page after the upload. The upload works great with the forms.ImageFile element, but I was looking for some ideas on how to do the actual resizing and and linking between the thumb and the true size images. I had an idea to hold model class for both an image and an image thumb:
from django.db import models
class Image(models.Model):
"""a true size image"""
image = models.ImageFile(upload_to="images")
desc = models.CharField(max_length=256)
class Meta:
db_table = "images"
class ImageThumb(models.Model):
""""a thumbnail of an actual image"""
real_image = models.ForeignKey('Image')
image = models.ImageField(upload_to="images/thumbs")
class Meta:
db_table = "thumbs"
That part I'm stuck on is how to resize the real image after upload (pil? how?), and I could probably use some polishing on my models - any help will be great. Thanks.
There's a great plugin called sorl-thumbnail that deals with thumbnail generation - don't bother doing it yourself. sorl-thumbnail is very configurable, so the chances are it'll do anything you want it to do.
If that doesn't work for you, then photologue is also very good (photologue is more tailored towards managing photo albums, rather than just plain thumbnail generation).
See also easy-thumbnails and aino-convert. They might be a good bet since sorl-thumbnail might not be developed very actively from now on.
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?
Is there a ImageList field that I don't know about?
Is there an app like django.contrib.comments that does the job for me?
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 =(
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".
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.
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
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.
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.
There is a package named django-galleryfield. I think it will meet your demand.