Having more than one PDF field on a table in Django - 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/

Related

How to setup a flexible django models

I'm new to django. What I'm trying to achieve is when the ProductType combobox is changed, the fields changes to its specific fields then the users inputs using those field and entered to the database. My problem is how to create a flexible model that would accept extra fields
from django.db import models
class Product(models.Model):
"""SKU"""
stock = models.IntegerField(default=None)
class ProductType(models.Model):
product_field = models.ForeignKey(ProductFields, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
class ProductFields(models.Model):
"""Fields of ProductType"""
Here's an DB example I'm trying to achieve See Image
SQL database is not suitable for that purpose.
Look for non-SQL databases for ex. Firebase

Django - How can Django ORM manage user's uploaded tables in database

My web application allow users to load/create tables in the Postgres database. I know Django ORM needs a model definition in models.py for each table in the database to access it. How can I access the user's uploaded tables in the app without creating a new model definition on the fly each time a new table is uploaded? I was thinking about creating a generic model definition that decompose the table into its components like this:
models.py
class Table(models.Model):
filename = models.CharField(max_length=255)
class Attribute(models.Model):
table = models.ForeignKey(Table)
name = models.CharField(max_length=255)
type = models.IntegerField()
width = models.IntegerField()
precision = models.IntegerField()
class Row(models.Model):
table = models.ForeignKey(Table)
class AttributeValue(models.Model):
row = models.ForeignKey(Row)
attribute = models.ForeignKey(Attribute)
value = models.CharField(max_length=255, blank=True, null=True)
The problems with such a generic model is that every tables are mixed in 4 table (not useful in admin interface) and its really slow to create when you have a lot of rows. Do you have suggestion with this case?
Edit: Could it be viable to use a separate database to store those tables and use a router and manage.py inspectdb to update its models.py each time a user add or delete a table? (like in this post) I wonder what would happen if two users add a table in the same time?
I think you should look into dynamic models like here:
https://code.djangoproject.com/wiki/DynamicModels
or here:
http://dynamic-models.readthedocs.org/en/latest/
Good luck because its not an easy way my friend :)
You'll probably need to use raw SQL queries for doing this.
If the schema of the tables you are expecting are predefined you can use a database router to link some model to a specific table name for each user.

Django Multiple File Field

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

whats the difference between Django models and forms?

I am new to Django and can't understand the models and forms. Can any one suggest me the differences and tutorials related to them.
Basically, a model encapsulates information about something (i.e., it models it), and is stored in the database. For example, we could model a person:
from django import models
class Person(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
height = models.FloatField()
weight = models.FloatField()
Whenever a model instance is created and saved, Django stores it in the database for you to retrieve and use at a later date.
On the other hand, forms correspond to HTML forms, i.e., a set of fields which are presented to the end user to fill some data in. A form can be completely independent of a model, for example a search form:
from django import forms
class SearchForm(forms.Form):
search_terms = forms.CharField(max_length=100)
max_results = forms.IntegerField()
When submitted, Django takes care of validating the values the user entered and converting them to Python types (such as integers). All you then have to do is write the code which does something with these values.
Of course, if you have created a model, you will often want to allow a user to create these models through a form. Instead of having to duplicate all the field names and create the form yourself, Django provides a shortcut for this, the ModelForm:
from django.forms import ModelForm
class PersonForm(forms.ModelForm)
class Meta:
model = Person
As for further reading, I would start with the Django documentation, which includes a tutorial on creating and using models, and a fairly in-depth look at forms. There are also plenty of Django books and online tutorials to help you along.
Models are related to the database abstraction layer covered in Tutorial 1:
http://docs.djangoproject.com/en/dev/intro/tutorial01/
It covers everything from what they are, what the philosophy is, what it's abstracting (raw sql). Read it and come back if you have any questions, because it's really good.
Tutorial 4 covers forms.
http://docs.djangoproject.com/en/dev/intro/tutorial04/
The forms framework is just a helper for HTML forms. There are also ModelForms, based on the forms framework, that ties models together with forms, but the core of it is a framework for dealing with HTML form display, validation, and processing.

Show related inlines in the admin on form of model with GenericForeignKey

I have simple models with generic relations from this example at the Django Project:
class Image(models.Model):
image = models.ImageField(upload_to="images")
class ImageLink(models.Model):
image = models.ForeignKey(Image)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey("content_type", "object_id")
class Product(models.Model):
name = models.CharField(max_length=100)
It's very simple to show inline ImageLink objects on the admin form of Product. It is demonstrated in the Django docs.
Can anyone suggest how have related ImageLinks inline on the admin form of an Image model?
IMPORTANT UPDATE: Updated example of model, becourse with previous, as Daniel sayd, it's not need to show objects inline.
It's neccessary use generic.GenericTabularInline for showing ImageLink objects inline on the Product form, as demonstrated in the Django docs.
But if we need to show related ImageLink inline on the Image form, it can be done with simple child of admin.TabularInline class.
It's very simple solution. I think I'm stupid not to guess it right away.
You don't have any related Products to show inline. Generic foreign keys, like normal ones, are one-to-many, with the 'one' side of the relation being the one containing the foreign key field. So in your case you still only have one Product for each Image, so there is no inline set to show.