working on a project, where i came to a small problem with QuerySets. (Look at the bottom to see a short diagram of my model structure.) I tried to query some information of a BLOG-Model starting from the Collection-Model. Now is it better to query first the Entrie-Model and find somehow the Collection to afterwards find the Blog-Model and add the information in the end to the Collection? Or is there a better / faster way to get information directly from the parent Model? Normaly it is easy if you just have 1:n->1:n Relations because you can easily follow the foreignkey, but this confuses me.
Here a short overview of my model structure:
<--------------- QUERY DIRECTION ----------------
(BLOG) --(1:N)--> (ENTRIE) <--(N:1)-- (COLLECTION)
BR, Felix
django's relations works both ways so if you need blog model from collection model you can directly query your Blog model so from your diagram:
class Blog:
entrie = models.ForeignKey(Entrie, on_delete=CASCADE)
class Entrie:
pass
class Collection:
entrie = models.ForeignKey(Entrie, on_delete=CASCADE)
so your query can be something like if you have not specified any related_name attributes on your models relation fields
Blog.objects.filter(entrie__collection={your_data})
Related
Assume I have a model named MyModel and I have a Field Named field Now I want to add three more fields inside the prescription like one field_a , field_b and field_c .
Does Django Allow that in any way or we have to make another model for this purpose and then link with Foreign Key to MyModel?
Well I think it is an idea that could lead to some really hard to maintain code and should be well thought through.
That aside If you have a look at:
https://docs.wagtail.io/en/stable/topics/streamfield.html
It's a special field meant for cms applications that uses json in the field to model dynamic fields and validations for it.
Also if you run postgres this might help. https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/fields/#jsonfield
I'm trying to find a solution to the following problem with django models:
The app would add products to a shopping cart. The problem is that those products come from different models, and no matter where they come from, I'd like to use one ManyToManyField to incorporate them.
Suppouse I've two different kind of products from two different models:
Class ListOfProducts1(models.Model):
name= CharField()
price= IntegerField()
Class ListOfProducts2(models.Model):
name=CharField()
price=IntegerField()
The following model would be used for get the quantity and the product added(and then related to one particular order).
Here is the problem. Look to the field itemsadded, where I want to relate this field to ListOfProducts 1 and 2. I'd put both of them into the same field, but I've already know this is not possible. Just for better understanding of the problem here you have:
Class ProductsOrdered(models.Model):
itemsadded= OneToOneField(ListOfProducts1 and ListOfProducts2,on_delete=models.CASCADE)
Quantity = IntegerField()
Then the Order's model:
Class Orders(models.Model):
cart= ManyToManyField(ProductsOrdered)
The OneToOne fields can refer to only one table.
But you can use either GenericForeignKey or alternatives (which is better).
Look at this article: Avoid Django’s GenericForeignKey. It describes alternatives, such as:
nullable fields on source table
intermediate table with nullable fields
intermediate table with OneToOneFields on destination models
multi-table inheritance
multiple linked models
Is there a way of filtering prefetched objects? I need to get the latest() of the prefetched objects but prefetch_related doesn't work if you use latest because the query is changed?
The example here does what I need but I was hoping there's a simpler workaround...
https://github.com/ionelmc/django-prefetch#example
As of Django 1.7, filtering prefetched objects is possible. See this SO answer, and the Django documentation.
It is very simple method which is hardly comparable with those app, but hope you will find it useful:
class Author(models.Model):
name = models.CharField(max_length=100)
def latest_book(self):
return max(self.book_set.all(), key=lambda book: book.created)
authors = Author.objects.prefetch_related('book_set')
authors[0].latest_book() # what you wanted
Yes, it can be done in this way :
authors=Author.objects.prefetch_related('book_set')
If you want to filter by an attribute(name) present in Author model you can simply filter it by writing:
authors.filter(name='your_value')
But if you want to apply filter on the Books model you have to write the following way:
authors.filter(book__created__gt='your_date')
This will filter all the books that have create date(created attribute in the Book module) greater than your date.
How do I travel through multiple foreign keys in Django? I've tried everything I can think of from the django docs, but I'm obviously missed something (extreme newbie). I have models for scientists, experiments, and theories.
If I want to look at a particular Theory (let's call it 'relativity') and get a list of all of the emails of scientists working on it (kept in the normal django user model), how do I do this?
class Experiment(models.Model)
experimenter = models.ForeignKey(Scientist)
theory = models.ForeignKey(Theory)
class Theory(models.Model)
name = models.CharField(max_length=100)
class Scientist(models.Model)
user = models.ForeignKey(User, unique=True)
institution = models.CharField(max_length=20, null=True, blank=True)
These are simplified versions of my models that I rewrote, so there are probably some errors in it, but the relationships are correct.
I've tried every kind of combinations of select_related(), get(), filter() but can't figure it out. Thanks in advance for your help!
User.objects.filter(scientist__experiment__theory__name=u'relativity')
Take a look at the Django documentation section about Lookups that span relationships. The net takeaway is:
To span a relationship, just use the field name of related fields across models, separated by double underscores, until you get to the field you want.
Ignacio's answer shows an example of using the double underscores on field names to span a relationship.
The other relevant portion of Django's documentation would be the Related objects section. Relationships in Django are asymmetrical in the way they are accessed. Forward/normal relationships are accessed as attributes of the models. Backward relationships are accessed:
Django also creates API accessors for the "other" side of the relationship -- the link from the related model to the model that defines the relationship. For example, a Blog object b has access to a list of all related Entry objects via the entry_set attribute: b.entry_set.all().
I'm building an ecommerce website.
I have a Product model that holds info common to all product types:
class Product(models.Model):
name=models.CharField()
description=models.CharField()
categories = models.ManyToManyField(Category)
Then I have SimpleProduct and BundleProduct that have FK to Product and hold info specific to the product type. BundleProduct has a m2m field to other Products.
class SimpleProduct(Product):
some_field=models.CharField()
class BundleProduct(Product):
products = models.ManyToManyField(Product)
When displaying the catalog I'm making one query against the Product model
and then another query per product to get the additional info.
This involve a large number of queries.
I can improve it by using select_related on the simpleproduct and bundleproduct fields.
I can further improve it by using the select_reverse app for m2m fields like categories.
This is a big improvement but there are more required queries because a BundleProduct have several products which can also have relations to other products (configurable product).
Is there a way to have a single query against Product that will retrieve the m2m categories, one2one SimpleProduct and BundleProduct and the BundleProduct's products?
Will this custom query look like a django queryset with all the managers and properties?
Thanks
You can possibly take a look at the extra method of querysets. May give you the opportunity to add some additional fields. But if you want raw queries, you can use the raw method of managers, these will return a type of queryset, that will not however harness the full power of normal querysets but should be enough for your concerns. On that same page the execute method is also shown, this is for truly custom sql that can't even translate into raw querysets.