En regardant la fonction add_aggregate
dans les django/db/models/sql/query.py
, objets de requête ne seront pas acceptées comme valeurs d'entrée.
Malheureusement, il n'y a actuellement aucun moyen direct au sein de Django pour agréger/annoter sur ce qui équivaut à un queryset, surtout pas celui qui est en outre filtré en quelque sorte.
En supposant que les modèles suivants:
class Item(models.Model):
name = models.CharField(max_length=32)
class Tag(models.Model):
itemfk = models.ForeignKey(Item, related_name='tags')
name = models.CharField(max_length=32)
class FavoritedTag(models.Model):
user = models.ForeignKey(User)
tag = models.ForeignKey(Tag)
De plus, vous ne pouvez pas annoter un queryset sur les champs définis par .extra()
.
On pourrait tomber dans SQL views.py
comme ceci:
from testing.models import Item, Tag, FavoritedTag
from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required
from django.utils.datastructures import SortedDict
@login_required
def interest_level(request):
ruid = request.user.id
qs = Item.objects.extra(
select = SortedDict([
('interest_level', 'SELECT COUNT(*) FROM testing_favoritedtag, testing_tag \
WHERE testing_favoritedtag.user_id = %s \
AND testing_favoritedtag.tag_id = testing_tag.id \
AND testing_tag.itemfk_id = testing_item.id'),
]),
select_params = (str(ruid),)
)
return render_to_response('testing/interest_level.html', {'qs': qs})
Modèle:
{% for item in qs %}
name: {{ item.name }}, level: {{ item.interest_level }}<br>
{% endfor %}
J'ai testé cela en utilisant MySQL5. Puisque je ne suis pas un expert SQL, je serais curieux de savoir comment optimiser ici, ou s'il y a une autre façon de "réduire" la quantité de SQL. Peut-être qu'il existe un moyen intéressant d'utiliser la fonctionnalité ici directement dans SQL?
-vous obtenez un message d'erreur? Pourriez-vous fournir les modèles avec lesquels vous travaillez? – cethegeek
l'erreur est "exception 'Q' objet n'a pas d'attribut 'split'", geradeausanwalt est droit fonctions d'agrégation ne prennent pas les objets Q comme arguments. Les modèles dans sa réponse sont similaires au mien. – Evgeny