2009-10-06 6 views
2

Cela semble étrange, mais c'est une idée très simple. J'essaye de faire un simple Flickr pour un site Web que je construis. Ce problème spécifique vient quand je veux montrer une seule photo (de mon modèle Photo) sur la page mais je veux également montrer l'image avant elle dans le flux et l'image après elle.Obtenir des enregistrements avant et après la sélection en cours dans la requête Django

Si je ne faisais que trier ces flux par date, ou que je ne faisais que trier par ID, cela pourrait être plus simple ... Mais je ne le suis pas. Je veux permettre à l'utilisateur de trier et filtrer par toute une variété de méthodes. Le tri est simple. J'ai fait cela et j'ai un ensemble de résultats, contenant 0-many Photo s.

Si je veux un seul Photo, je commence avec ce flux filtré/trié/etc. De là, je dois obtenir le Photo actuel, le Photo avant et le Photo après.

Voici ce que je regarde en ce moment.

prev = None 
next = None 
photo = None 

for i in range(1, filtered_queryset.count()): 
    if filtered_queryset[i].pk = desired_pk: 
     if i>1: prev = filtered_queryset[i-1] 
     if i<filtered_queryset.count(): next = filtered_queryset[i+1] 
     photo = filtered_queryset[i] 
     break 

Il semble juste disgracieusement désordonné. Et inefficace. Oh mon seigneur, si inefficace. Quelqu'un peut-il améliorer cela?

Les requêtes de Django sont tardives, donc ce serait bien d'en faire usage même si je suppose que cela pourrait être impossible étant donné mes horribles restrictions. Edit: il me vient à l'esprit que je peux juste jeter un peu de SQL pour re-filtrer le queryset. S'il y a un moyen de sélectionner quelque chose avec ses deux (ou un, ou zéro) voisins les plus proches avec SQL, j'aimerais bien le savoir!

+0

On dirait que vous essayez de créer des index là où vous n'en avez pas. Si vous aviez un groupe de personnes et que vous en avez choisi un parmi la foule, vous avez dit: «Trouvez-moi la prochaine personne la plus grande et la plus proche par rapport à cette personne», sinon, comment le feriez-vous? –

+0

"Ensuite, et seulement alors, puis-je voir si mon image est dans cette sélection" <- Pourriez-vous expliquer pourquoi c'est le cas? Vous n'avez pas l'identifiant de l'image dans l'URL? –

+0

@Emil J'ai le pk de l'image voulue mais j'ai besoin de le localiser dans la liste (ce qui implique de le parcourir si dessus est la seule option). Je ne peux pas filtrer à nouveau (ou '.get()') parce que ça m'empêcherait d'obtenir prev/next Photos – Oli

Répondre

1

Vous pouvez essayer ce qui suit:

  1. Évaluer la queryset filtrée/triée et obtenir la liste des ids photos, que vous tenez dans la session. Ces identifiants correspondent tous aux critères de filtrage/tri.
  2. Conservez également l'index actuel dans la liste de la session et mettez-le à jour lorsque l'utilisateur passe à la photo précédente/suivante. Utilisez cet index pour obtenir les identifiants prev/current/next à utiliser pour afficher les photos.
  3. Lorsque les critères de filtrage/tri changent, réévaluez la liste et définissez l'index actuel sur une valeur appropriée (par exemple, 0 pour la première photo de la nouvelle liste).
+0

Je vais devoir changer la façon dont je stocke les fichiers, mais cela pourrait très bien fonctionner. Pour plus de rapidité, je vais utiliser memcached à la place des sessions afin que la mise en cache des requêtes soit partagée entre les utilisateurs. – Oli

1

Je vois les possibilités suivantes:

  1. Vos paramètres de requête d'URL contiennent les informations de tri/filtrage et une sorte de « numéro d'article », qui est le numéro d'article au sein votre queryset filtrée. Ceci est le cas simple - précédent et suivant sont numéro d'article moins un et plus un (respectivement plus de vérification des bornes)

  2. Vous voulez que l'URL soit un lien permanent, et contenir la clé primaire de la photo (ou un ID unique) . Dans ce cas, vous stockez vraisemblablement le tri/filtrage dans:

    • dans l'URL en tant que paramètres de requête. Dans ce cas, vous n'avez pas de véritables permaliens, et vous pouvez également coller le numéro d'article dans l'URL, vous revenant à l'option 1.
    • champs masqués dans la page, et en utilisant POSTs pour les liens au lieu de liens normaux. Dans ce cas, collez le numéro de l'article dans les champs cachés.
    • données de session/cookies. Cela se casse si l'utilisateur a deux onglets ouverts avec différents types/filtrage appliqués, mais cela pourrait être une limite que vous ne voyez pas d'inconvénient - après tout, vous avez envisagé qu'ils utiliseraient probablement un seul onglet et en cliquant sur la liste. Dans ce cas, stockez également le numéro d'article dans la session. Vous pourriez être en mesure de faire quelque chose d'intelligent à "namespace" le numéro d'article pour le cas où ils ont plusieurs onglets ouverts.

En bref, mémoriser le numéro de l'article chaque fois que vous stocker les informations de filtrage/tri.

+0

# 1 créerait des permaliens non permanents si l'ordre/le contenu du flux changeait (et il le fera). # 2 même, je pense. Ces flux auront des choses ajoutées et il y a une note, donc le score de chaque photo va changer avec le temps. La mise en cache de session/cookie peut fonctionner mais c'est un peu sale. – Oli

+0

Où stockez-vous réellement le tri/filtrage? – spookylukey

Questions connexes