Exclude a queryset from bigger queryset in django without hitting the database - python

I have a queryset of all objects of a model. Iterating over the objects, I am removing updating rows with value repetition in a column. So without having to hit the database again, i want to remove the updated rows from the bigger queryset.
What is the most efficient way to do this?

You may need to provide more information about your specific use case, but in general, Django defers the evaluation of QuerySets until they are actually needed. If you are able to construct a QuerySet of the exclusion set independently of the larger QuerySet, you can call the .exclude() method and generate one large query instead of two smaller ones. For example:
excluded_set = Model.objects.filter(...)
large_set = Model.objects.filter().exclude(id__in=excluded_set)

Related

Is there a way to merge the results of many QuerySets into a single QuerySet in Django?

I have a list of QuerySets (qs1, qs2, ..., qsn), whose length is not fixed (it varies depending on other variables). I need to merge all those QuerySets into a single QuerySet. I have something like this:
list1 = [qs1, qs2, ..., qsn]
I know there's a function in Django that allows me to do just this, but only if I know exactly how many QuerySets I want to join. Since in this case the number of QuerySets in the list (the ones that I want to merge) varies, I can't use
qs1.union(qs2, qs3)
because I won't always have just those three QuerySets in my list, sometimes I'll have just one or just two, or a thousand.
Knowing that the length of the list is not fixed and that I need a final QuerySet that includes the results of all of the QuerySets within the list list1, no matter how many QuerySets it contains, is there a function that allows me to merge all the QuerySets inside this list into a single QuerySet? Thanks so much in advance.
According to Django Documentation, you can use qs1.union(*queryset_list)

Django the fastest way to do Query get list of items in row from table

In my app I need to do fast Query but I don't know which is faster
materials = Material.objects.only('name')
Or do filter this in view
materials = Material.objects.all()
And then use for loop to show list of items from 'name' row
I think that first is better or there is better way to do this?
It cant be done with filter() because it need to show all of fields in this row.
If you only want the names, you can use a .values_list(..):
materials = list(Material.objects.values_list('name', flat=True))
This will avoid wrapping the records in Material objects. That being said, unless some of the columns contain (very) large amounts of data, using .only(..) will not significantly speed up the process. Furthermore software design-wise it is often better to fetch Material objects, since that means that you can define behavior in your Material model.

NDB: Sort query results

In App Engine NDB, I am querying entities that have a repeated property. I would like to order the result by the length of the array representing that property.
What I wish I could do:
Entity.query(...).order(len(Entity.repeatedProp))
You'll need to add an ndb.IntegerProperty() to your entity where you will store the length of the repeated property. Every time you change your repeated property, you'll need to update the stored length. Then you sort based on that stored length.
You could probably use a computed property, but I've never used one of those so I'm not sure.
Depending on how many entities are you sorting you can sort it by code.

Django - how can I have a field in my model consisting of tuple of integers?

I am defining the models for my Django app, and I would like to have a field for a model consisting of a tuple of two (positive) integers. How can I do this? I'm looking at the Django Models API reference but I can't see any way of doing this.
Depends on how you intend to use them after storing in the database; 2 methods I can think of are:
Option 1)
models.IntegerField(unique=True)
now the trick is loading data and parsing it: you would have to concatenate the numbers then have a way to split them back out.
fast would be
Option 2)
models.CommaSeparatedIntegerField(max_length=1024, unique=True)
not sure how it handles unique values; likely '20,40' is not equal to '40,20', so those two sets would be unique.
or just implement it yourself in a custom field/functions in the model.

Ordered lists in django

i have very simple problem. I need to create model, that represent element of ordered list. This model can be implemented like this:
class Item(models.Model):
data = models.TextField()
order = models.IntegerField()
or like this:
class Item(models.Model):
data = models.TextField()
next = models.ForeignKey('self')
What way is preferred? What drawbacks have each solution?
Essentially, the second solution you propose is a linked list. Linked list implemented at the database level are usually not a good idea. To retrieve a list of n elements, you will need n database access (or use complicated queries). Performance wise, retrieving a list in O(n) is awfully not efficient.
In regular code, linked list are used to get better insert performance compared to arrays (no need to move all elements around). In your database, updating all elements is not that complicated in only 2 queries :
UPDATE item.order = item.order + 1 FROM item WHERE order > 3
INSERT INTO item (order, ...) VALUES (3, ...)
I remember seeing a reuseable app that implemented all that and a nice admin interface, but I cant find it right now ...
To summarize, definitly use solution #1 and stay away from solution #2 unless you have a very very good reason not to !
That depends on what you want to do.
The first one seems better to make a single query in the database and get all data in the correct order
The second one seems better to insert an element between two existing elements (because in the first one you'd have to change a lot of items if the numbers are sequential)
I'd use the first one, because it seems to fit better a database table, which is how django stores model data behind the hood.
There is another solution.
class Item(models.Model):
data = models.TextField()
You can just pickle or marshal Python list into the data field and the load it up. This one is good for updating and reading, but not for searching e.g. fetching all lists that contain a specific item.

Categories