so I started working with Django recently, I’m having a case of many-to-many relationship between Book and Author -as simple example- a book could have multiple authors.
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField('Author', related_name='books')
def __str__(self):
return self.title
class Author(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
My goal is to fetch the data of Book, but the problem is when a book has multiple authors, I get the same book row for each of its authors, the question is can I have a book row with all its authors stored in a list ? instead of a row for each author.
Example of data fetching as JSON:
[
{
"id": 1,
"title": "Good Omens",
"authors__name": "Neil Gaiman"
},
{
"id": 1,
"title": "Good Omens",
"authors__name": "Terry Pratchett"
},
{
"id": 2,
"title": "The Lord of the Rings",
"authors__name": "J.R.R. Tolkien"
}
]
So I want something like this instead:
{
"id": 1,
"title": "Good Omens",
"authors__name": ["Neil Gaiman", "Terry Pratchett"]
},
While it’s easy to implement this via python code, I want a solution using model queries or ORM methods, to gain some performance and time since the data will be so big.
The following code shows a method responsible to get the data and to do some ordering and filtering, all using queries:
def __model_query(self, model_class, fields=None, enum_fields=None, order_by=None, search=None, field_search=None):
queryset = model_class.objects.all()
# Apply ordering if specified
if order_by:
field_name, sort_order = order_by
if sort_order == "desc":
queryset = queryset.order_by(f"-{field_name}")
elif sort_order == "asc":
queryset = queryset.order_by(field_name)
# Apply general search if specified
if search:
search_filters = Q()
for field in fields:
search_filters |= Q(**{f"{field}__icontains": search})
queryset = queryset.filter(search_filters)
# Apply field-specific search if specified
if field_search:
search_filters = Q()
for field, value in field_search.items():
if enum_fields and field in enum_fields:
search_filters |= Q(**{f"{field}__exact": value})
else:
search_filters |= Q(**{f"{field}__icontains": value})
queryset = queryset.filter(search_filters)
return queryset
I’m using sqlite3 db currently so I can’t use any method related to Postgres db.
I really thank you who ever can help me with this, I hope I provided all the details needed.
I didn’t try much solutions, just ones provided by ChatGPT but they are all failed.
Imad Fen is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.