I have a twisty maze of interrelated Django models, with many-to-many fields describing the relationships.
What's the cleanest way to get a list of unique members of a related model from a QuerySet?
If I have a Item model with a groups ManyToMany pointing to the Groups model.
If I have a queryset of Items, of 'items', how do I get this:
groups = items[0].groups.all().values_list('name', flat=True)
But for the whole set? Do I need to iterate through them all and do set().intersect() ?
One solution is to use 2 queries.
You can use the reverse relationships to query all Groups that an Item in your items points to.
groups = groups.objects.filter(item__in=items).distinct().values_list('name', flat=True)
Related
I have a DJANGO Profiles model and a Answer model with a foreignkey to Profile
Imagine that every Profile will have multiple Answers like lists of integers
What I want is to order my queryset by the most similar answers to mine.
So I found this method (rmse) to compare arrays: np.sqrt(((list_a - list_b) ** 2).mean())
If the arrays are equals this returns 0 and so on..
How can I create a Annotation to Profiles queryset that compare my answers to others using this method above?
I tried to extract the data using 'tablename.objects.Fname()' but I am still confused on how to store all the first names in the array from database.
if yes could anyone provide with an example, any sort of help would be appreciated.
You can obtain the values stored in a column by using .values(…), or .values_list(…). For example:
tablename.objects.values_list('Fname', flat=True)
This QuerySet is an iterable that for each record will contain one element with the cleaned value of that record. So if it is an ArrayField, it will contain a collection of lists.
But using an ArrayField [Django-doc] or other composite field is often not a good idea. It makes the items in the array harder to process, filter, JOIN, etc. Therefore it is often better to make an extra table, and define a many-to-one relation, for example with a ForeignKey [Django-doc].
Model Model1 has ForeignKey field (my_field) to Model2. I want to retrieve all Model1 without records that already have at least 1 record with same my_field value.
I think you need to get all distinct records from Model1, So this is how you can do it in django.
Model1.objects.all().distinct()
Hope this would answer your question.
Thanks
I'm setting up my Models and I'm trying to avoid using ManyToMany Relationships.
I have this setup:
Model: Human
Some Humans (a small percentage) need to have M2M relationships with other Humans. Let's call this relationship "knows" (reverse relationship called "is_known_by").
To avoid setting a ManyToManyField in Humans, I made a Model FamousHumans.
FamousHumans are a special class of Human and have a OneToOneField(Human)
They also have a ManyToManyField(Humans) to represent the "knows" relationship
Here is my question:
Since Django creates reverse relationships, I assume that all Humans will have a reverse "is_known_by" relationship to FamousHumans, so there is still a M2M relationship. Is there any performance benefit to my setup?
The dataset will be rather large and only a few Humans will need the M2M relationship. My main concern is performance.
This is unnecessarily complex.
There is no performance overhead to having a many-to-many relationship. This is represented by an intermediary table in the database; there's no actual field in the humans table. If an item doesn't have any m2m members, then no data is stored.
I have a Product model, with a one-to-many relation with a Rating model. I was previously storing an average_stars field in Product model, which I would update everytime a new Rating was added for that Product model. I would have a function in views.py which would return a QuerySet of all Product instances, ordered by average_star. Is there a way to do this more dynamically using a combination of .aggregate and .order_by, or anything along these lines.
In other words, is there a way to calculate the average for each product from all its respective Rating models, and sort them by that attribute? And which approach is better?
Assuming that your Rating model has a stars field, then you should use annotate:
from django.db.models import Avg
Product.objects.annotate(average_stars = Avg('rating__stars')).order_by('-average_stars')