Efficient method to update one field with different values in a django model - django

I have many pk-value in a dictionary and I want to update the object with his new value.
to_update = [{'id':id1,'value':value1}, ... ]
Now i'm doing this:
for t in to_update:
Mymodel.objects.filter(pk=t['id']).update(myfield=t['value'])
I think that i can do this in a better way, but i didn't find it.

This is the most efficient way. QuerySet.update() is converted directly to an UPDATE statement, and there is no more efficient way of doing it than that.

Related

How to copy a solution of a PySCIPOpt model to another model?

Given a pyscipopt.Model and its Solution, how to pass it to another model as a primal heuristic?
I'm currently writing the solution to a file via writeSol(), and then calling readSolFile() and addSol(). There should probably be a cleaner way.
This depends a bit on the structure of your two models. If they have the same variables in the same order (which is likely from what you wrote), then you can simply create a new solution in your model and copy all the values, ie:
variables = othermodel.getVars()
newvariables = model.getVars()
nvars = othermodel.getNVars()
newsol = self.model.createSol(self)
for i in range(nvars):
newsol[newvariables[i]] = othermodel.getSolVal(oldsol, variables[i])
self.model.trySol(newsol)
Let me know if this work/ doens't work

Get part of django model depending on a variable

My code
PriceListItem.objects.get(id=tarif_id).price_eur
In my settings.py
CURRENCY='eur'
My Question:
I would like to pick the different info depending on the CURRENCY variable in settings.py
Example:
PriceListItem.objects.get(id=tarif_id).price_+settings.CURRENCY
Is it possible?
Sure. This has nothing to do with Django actually. You can reach the instance's attribute through pure Python:
getattr(PriceListItem.objects.get(id=tarif_id), 'price_'+settings.CURRENCY)
Note it might be a better idea to have a method on the model which accepts the currency as a parameter and returns the correct piece of data (through the line I wrote above, for example).
I think this should work
item = PriceListItem.objects.get(id=tarif_id)
value = getattr(item, price_+settings.CURRENCY)
In case you are only interested in that specific column, you can make the query more efficient with .values_list:
my_price = PriceListItem.objects.values_list_(
'price_{}'.format(settings.CURRENCY),
flat=True
).get(id=tarif_id)
This will only fetch that specific column from the database, which can be a (a bit) faster than first fetching the entire row into memory, and then discard all the rest later.
Here my_price is thus not a PriceListItem object, but the value that is stored for the specific price_cur column.
It will thus result in a query that looks like:
SELECT pricelistitem.price_cur
FROM pricelistitem
WHERE id=tarif_id

Django 1.6 How to change a list to queryset or How to write this kind of query?

I want to get all the questinos with no answers.I use this:
all_questions=[q for q in Question.objects.all() if not q.answer_set.all()]
It works. But then I need to invoke order_by method with all_questions, so I need to change it to a queryset, how?
Or, is there a standard method like Question.objects.filter(answer_count=0) ? I find hard but no results.
Solution: Change answer_count__gt=0 to answer_count=0.
all_questions=Question.objects.annotate(answer_count=Count('answer')).filter(answer_count=0)
You should be able to use an annotation much more efficiently than doing one query per question.
Question.objects.annotate(answer_count=Count('answer')).filter(answer_count=0)
That said, you could just add the order_by directly into your Questions.objects.all() query. But like I said, it's much less efficient to do a query per question.

django queryset ordering

I'm listing queryset results and would like to add an option for choosing the order results are displayed.
I would like to pass the actual data from the database to other page for sorting.
I was able to achieve such thing by getting all objects ids and use django session to recreate a new queryset based on the order criteria.
I was thinking if there is any other way to achieve such goal?
10x
Assuming you are currently displaying the data as a table, you could give chance to some javascript client side table sorter such as tablesorter. There are lots of javascript table sorte.
I'm away from my development machine right now, but I think you could just pass the list of ids to a new Queryset, pk__in=list_of_object_ids, and then use the native order_by function.
For example:
objs = Object.objects.filter(pk__in=list_of_object_ids).order_by('value_to_order_by')
Anyway, that's what I would try first, though I'm sure there are better optimizations.
For example, instead of a list of object ids, you could pass a dictionary with a key:value pair that has the value you want to order by.
For example:
[{'obj_id':1,'obj_value':'foo'},{'obj_id':2,'obj_value':'foo'}]
Then use some lambda function to sort it, like here.

Passing limited queryset to related_to() in django-tagging

I want to use the related_to() function in django-tagging and I am passing a queryset looking like this:
Chapter.objects.all().order_by('?')[:5] #the important thing here is the "[:5]"
My problem is that this function apparently uses the in_bunk() function and you Cannot use 'limit' or 'offset' with in_bulk
How can I restrict my queryset to only pass 5 objects and at the same time make use of in_bunk?
I know that related_to() lets you pass the variable num (which is the number of objects it should return) but I don't want it to output the same queryset every single time. So i came up with the idea of ordering it randomly and limiting it before it was passed to the function. But as you can see: limited querysets and bunk_it doesn't go hand in hand very well.
I found a solution though it wasn't the best and though it processes unnecessary data. I simply run through all instances of the model related to the current instance and I then sort randomly and slice afterwards:
related_objects = instance.related_to(Model) # all related objects are found
related_objects = random.sample(related_objects,5) # .. and afterwards sorted randomly and sliced