Django Multiple File Field - django

Is there a model field that can handle multiple files or multiple images for django? Or is it better to make a ManyToManyField to a separate model containing Images or Files?
I need a solution complete with upload interface in django-admin.

For guys from 2017 and later, there is a special section in Django docs. My personal solution was this (successfully works in admin):
class ProductImageForm(forms.ModelForm):
# this will return only first saved image on save()
image = forms.ImageField(widget=forms.FileInput(attrs={'multiple': True}), required=True)
class Meta:
model = ProductImage
fields = ['image', 'position']
def save(self, *args, **kwargs):
# multiple file upload
# NB: does not respect 'commit' kwarg
file_list = natsorted(self.files.getlist('{}-image'.format(self.prefix)), key=lambda file: file.name)
self.instance.image = file_list[0]
for file in file_list[1:]:
ProductImage.objects.create(
product=self.cleaned_data['product'],
image=file,
position=self.cleaned_data['position'],
)
return super().save(*args, **kwargs)

No there isn't a single field that knows how to store multiple images shipped with Django. Uploaded files are stored as file path strings in the model, so it's essentially a CharField that knows how to be converted to python.
The typical multiple image relationship is built as a separate Image model with an FK pointing to its relevant model, such as ProductImage -> Product.
This setup makes it very easy to add into the django admin as an Inline.
An M2M field would make sense if you it's truly a many to many relationship where say GalleryImages are referenced from 1 or more Gallery objects.

I had to change from having a single file to multiple files in an existing system and after a bit of research ended up using this: https://github.com/bartTC/django-attachments
It should be easy to subclass the model if you want custom methods.

FilerFileField and FilerImageField in one model:
They are subclasses of django.db.models.ForeignKey, so the same rules apply. The only difference is, that there is no need to declare what model we are referencing (it is always filer.models.File for the FilerFileField and filer.models.Image for the FilerImageField).
Simple example models.py:
from django.db import models
from filer.fields.image import FilerImageField
from filer.fields.file import FilerFileField
class Company(models.Model):
name = models.CharField(max_length=255)
logo = FilerImageField(null=True, blank=True)
disclaimer = FilerFileField(null=True, blank=True)
Multiple image file fields on the same model in models.py:
Note: related_name attribute required, it is just like defining a foreign key relationship.
from django.db import models
from filer.fields.image import FilerImageField
class Book(models.Model):
title = models.CharField(max_length=255)
cover = FilerImageField(related_name="book_covers")
back = FilerImageField(related_name="book_backs")
This answer code taken from django-filer document

Related

Define list of objects in models.py in postgeSQL & Django-rest project

I mostly work with Node.js & MongoDB and I am pretty new to SQL dbs especially postgreSQL I am writing an application that makes use of django-rest-framework & postgreSQL as a DB.
This is how my data structure as .json should look like.
{
id: "19eea956-34e5-11eb-adc1-0242ac120002"
picture: [{
url: "",
mimeType: ""
},
{
url: "",
mimeType: ""
}]
}
For the above data I am currently writing models.py which looks like as follows.
from django.db import models
from django.contrib.postgres.fields import ArrayField
class Picture(models.Model):
url = models.CharField()
mimeType = models.CharField()
class A(models.Model):
id = models.CharField(max_length=120, primary_key=True)
picture = ArrayField(Picture)
def __str__(self):
return self.id
What I am trying to do in my models.py is to have picture as an Array of Objects or in python terminology List of Dictionaries.
I read about ArrayField in postgreSQL but unable to find any example about how to define Array of Objects in models.py, any help here would be appreciated.
Thanks :)
In relational databases relations are defined by Foreign Keys and different tables. Tables are represented by Django's models, but the programmer should work from the model side of things and think of the database as the object persistence (storage of the state of an object).
Fields should as a rule be single values, not containers. Explaining why distracts too much from the problem at hand, but here's the in-depth info.
In this case, you have two entities, let's call A "Gallery" for clarity. A Gallery object has 1 or more pictures. A picture can be associated with 1 gallery (business rule). There are 2 properties associated with the image: url and mime type.
Now there's several ways to deal with images and that depends whether the image is uploaded or really a URL to a remote image.
I'm going to pick the second option for brevity:
import uuid
from django.db import models
class Gallery(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
name = models.CharField(max_length=40)
class Picture(models.Model):
url = models.URLField()
mime_type = models.CharField(max_length=25)
gallery = models.ForeignKey(Gallery, on_delete=models.CASCADE, related_name='pictures')
This creates the correct relation for the image in a way that is preferred by both Django and relational databases.
Now we need to serialize the picture to just the url and mime type field:
from rest_framework import serializers
from .models import Picture, Gallery
class PictureSerializer(serializers.ModelSerializer):
class Meta:
model = Picture
fields = ['mime_type', 'url']
Continuing, we need to nest the pictures into the gallery:
class GallerySerializer(serializers.ModelSerializer):
pictures = PictureSerializer(many=True)
class Meta:
model = Gallery
fields = ['id', 'pictures']
And this should do the trick.
The reason people downvoted is most likely because this is a Q&A site and your scope as demonstrated by my answer is far too big for that. I've given you some handles to work with, but it's best you hit the Django tutorial to get a basic sense of models, followed by the DRF counterpart.

Django blogs using Rest framework connecting mutliple images to that content in single object

Is there anyway where we can build logic Using django rest framework
where user can add blog with multiple images and content accordingly and when saved
and retrieved it should be able to display the same kind of UI depening up on the frontend app
same like medium platform
Note:
My question isn't about adding multiple images and content using Rest framework
but its about fetching and displaying the data based on how user sent it the server
For eg:
<Image>
content for that image
<Image2>
content for this image
i just want to know how to associate those images to that content
i want to add content to that image
or is there anyway where we can store image and all the content exacty and save it in TextField
I've searched a lot about this but unfortunately I've not found a way to make this happen
Read about relationships in Django (and SQL in general)
django relations
it sounds like you're looking for something like the following:
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# Always override the user model provided by Django when starting a project. the docs themselves state that.
pass
class Image(models.Model):
image = models.ImageField()
added = models.DateTimeField(auto_now_add=True)
# using get_user_model to get the User model, always better then referencing User directly
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name="user_images",
null=False,
blank=False
)
class ImageContent(models.Model):
title = models.CharField(max_length=140, null=False, blank=False)
content = models.TextField(max_length=500)
image = models.OneToOneField(Image, on_delete=models.CASCADE, null=False, blank=False)
Some notes:
I haven't dealt myself with Images field But I remember it does require a special library (pillow).
getting the data in a certain order should be easy enough if you understand the queryset object:
queryset link
using stuff like order_by will help you return the response in the order you like.
the models I've written here are not the only way to achieve the goal you've set, I strongly recommend reading about relations and models in Django.

Differences between Stacked inline and Tabular inline

This is my models.py file
from django.db import models
# Create your models here.
class Item(models.Model):
name=models.CharField(max_length=250)
description = model.TextField()
class Meta:
oredering['name']
def __unicode__(self):
return self.name
#permalink
def get_absolute_url:
retun ('item_detail',None,{'object_id':self_id})
class Photo(models.Model):
item = models.ForiegnKey(Item)
title=models.ChaField(max_length=250)
image=models.IMageField(upload_to='photos')
caption=models.TextField(blank=True)
class Meta:
ordering=['title']
def __unicode__(self):
return self.title
#permalink
def get_absolute_url(self):
retun ('photo_detail',None,{'object_id':self_id})
And this is my admin.py :
from django.contrib import admin
from models import Item
from models import Photo
# Register your models here.
class PhotoInline(admin.StackedInline):
model = Photo
class ItemAdmin(admin.ModelAdmin):
inlines = [PhotoInline]
admin.site.register(Item, ItemAdmin)
admin.site.register(Photo)
But, I can't understand what is StackedInline and TabularInline, I referred to Django documentation but still couldn't understand what exactly it was.
Also, I can't see those models in my admin panel when I started the server, I don't understand why my models aren't registered on my admin page.
I see two different questions:
I cant understand what is stacked inline and tabular inline
Basically, both allow you to edit models on the same page as a parent model. In other words, it is sometimes preferable for a user to have the possibility to edit a certain model while editing another one instead of having to manually add another instance somewhere else in your interface. In your particular case, you can use it to facilitate user experience by allowing the user to add photos linked to a parent item simultaneously whitout having to constantly change between your admin forms.
Now, the difference between the two is really simple to understand: Layout. Indeed, both works exactly the same behind the scenes, the only difference is the template used for rendering. It can be seen here in the source code. So, picking one for your project is only a matter of preference regarding the interface layout
I cant see those models in my admin panel
This can be a lot of things, but often it's because you forgot to run your migrations with makemigrations and migrate. If you did, another thing that a lot of users forget is to install their app. So, in
Setting.py
INSTALLED_APPS = ['Myproject.apps.Myapp']
The TabularInline displays data in table
But StackedInline displays in row

Django app structutre and circular reference

I'm trying to keep my project well organized, so I try to keep it splitted to apps.
Assume a blog app with a BlogPost model.
Now I add to that a Tag app, which has a Tag model with foreign key to Post.
Now if I want to write a method get_tags(), in the Blog class, that would be circular reference.
So is that a bad design? Maybe I should not write such method on the blog, or such related models should simply be in the same app?
I'm Simply trying to learn how to organize my (big) project. I've read a lot about django app concept, stil haven't found a right way
The point here is that Django automatically creates reverse lookup when you create a ForeignKey or ManytoManyField. Assuming your models are as follows:
BlogPost Model
from django.db import models
class BlogPost(models.Model):
title = models.CharField(_('title'), max_length=200)
slug = models.SlugField(_('slug'), unique_for_date='publish')
author = models.ForeignKey(User, blank=True, null=True)
body = models.TextField(_('body'), )
publish = models.DateTimeField(_('publish'), default=datetime.datetime.now)
created = models.DateTimeField(_('created'), auto_now_add=True)
Tag Model
from django.db import models
from Blog.models import BlogPost
class Tag(models.Model):
Post = models.ForeignKey(BlogPost,related_name="tags")
Now, assuming you are generating the Tags of a post in a view, you can basically get all the tags of a post by just calling blogpost.tags_set where blogpost is a model instance of BlogPost.

Having more than one PDF field on a table in Django

I am making a Manual admin as part of a big project. Each manual has a brand, a model and has at least one PDF.
from django.db import models
class Manual(models.Model):
brand = models.CharField(max_length=255)
model = models.CharField(max_length=255)
manual = models.ImageField(upload_to='pdf')
Two questions:
How can I model a PDFField, or a generic field, rather than an Image field?
Is it possible for the manual field to have more than one file without having to make another table?
Thanks!
If you need to have more than one pdf per manual, use a one-to-many relationship as a ForeignKey in another table. There's nothing wrong with having multiple models.
class Manual(models.Model):
brand = models.CharField(max_length=255)
model = models.CharField(max_length=255)
class ManualPDF(models.Model):
manual = models.ForeignKey(Manual)
pdf = models.FileField(upload_to='pdf')
In your view code (or form or model code) you can then get all the PDFs for a manual using _set which will return a QuerySet of the ManualPDF model objects:
some_manual = Manual.objects.get(id=1)
some_manual_pdfs = some_manual.manualpdf_set.all()
There more info in the official Django docs:
https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_one/