django select_for_update and select_related on sam

2019-08-15 16:54发布

问题:

Does anyone know if you can do both the .select_for_update() and .select_related() statements in a single query? Such as:

employee = get_object_or_404(Employee.objects.select_for_update().
                              select_related(‘company’), pk=3)

It seemed to work fine in one place in my code, but a second usage threw an "InternalError: current transaction is aborted" for a series of unit tests. Removing the .select_related and leaving just .select_for_update made the error go away, but I don't know why. I'd like to use them both to optimize my code, but if forced to choose, I'll pick select_for_update. Wondering if there's a way I can use both. Using postgres and django 1.9. Thanks!

回答1:

You can't use select_related with foreign keys that are nullable when you are using select_for_update on the same queryset.

This will work in all cases:

Book.objects.select_related().select_for_update().get(name='Doors of perception')


回答2:

Since Django 2.0, you can use select_for_update together with select_related even on nullable relations - by using new parameter of=...

Using their Person example from docs, you could do

Person.objects.select_related('hometown').select_for_update(of=('self',))

which would lock only the Person object