Reputation: 674
I have this field in my model:
class PlayerDetailPage(Page):
picture = models.ForeignKey('wagtailimages.Image', null=True, on_delete=models.SET_NULL, related_name='+', help_text=_('Player profile picture.'))
And I want to create a inclusion tag, where I access different fields on this Wagtail page model. For db efficiency I use values but on the picture
field I want the full query set. Not just a value in a dictionary because I need to render the image.
Right now I have this view:
PlayerDetailPage.objects.values('title', 'path' , 'slug', 'owner__age', 'owner__nationality', )
So far so good, I am pulling only the fields I need and I get a nice dictionary with one query. However for the picture
field I want the full query set because it is a Wagtail picture field. It has some nice render options attached. How can I combine this in my view to get the best db efficient query?
And unfortunately direct url is not a field in the image model I guess it is a property, I tried picture__url
but that resolved in:
Cannot resolve keyword 'url' into field. Choices are: collection, collection_id, created_at, file, file_hash, file_size, focal_point_height, focal_point_width, focal_point_x, focal_point_y, height, id, renditions, tagged_items, tags, title, uploaded_by_user, uploaded_by_user_id, width
My view:
@register.inclusion_tag('wdashboard/tags/player_widget.html', takes_context=True)
def player_widget(context):
qs = PlayerDetailPage.objects.values('title', 'path' , 'picture__file', 'slug', 'owner__age', 'owner__nationality', )
for ins in qs:
ins['picture'] = Image(file=ins['picture__file'])
return {'values1': qs,'request': context['request'],}
Upvotes: 3
Views: 690
Reputation: 6598
The thing you are looking for is not possible without a tricky solution IMHO. The reason is that values
method runs a very well defined query only once on db and then converts results into dict
. So you are never going to get original PlayerDetailPage
object but a dict. For example if you have a model MyModel
and you do following
x = MyModel.objects.get(id=1)
print(type(x)) # <class 'MyModel'>
But for values the case is different
x = MyModel.objects.values('id').get(id=1)
print(type(x)) # <class 'dict'>
So you lose original object and get a dict.
A little clever solution
If you have no other choice then using values
, I would suggest following solution.
Build your query and also get data you need from Image
model.
qs = PlayerDetailPage.objects.values('picture__name') # assume there is a name field.
Now loop over qs
, initialize an Image
object, (don't save it) and add it to your dictionary like this
from wagtail.images.models import Image
for ins in qs:
ins['picture'] = Image(name=ins['picture__name'])
Now you have an picture
in your values qs as instance and you can use nice render options attached with it.
Upvotes: 2