8
votes

Modification de l'ordre d'affichage des formulaires dans un format

J'affiche un modelormset et j'aimerais que les formulaires soient commandés par le contenu de l'un de ses champs. Donc, je veux utiliser l'équivalent de somemodel.Object.filter (autre) .Order_by ("Certainsfield ') pour un fichier (modèle) dans un modèle.

Comment puis-je faire cela?

Notez que can_order ne fait pas ce que je veux (il doit être automatique, non spécifié par l'utilisateur). J'ai également essayé d'autres choses, comme le filtre Dictsort, mais qui produit une sortie imprévisible (c'est-à-dire non commandée par le champ spécifié).

J'ai même essayé {% regroupez le format de formulaire par certainsField comme trié_formset%} , mais le type résultat_formse ne peut pas être utilisé (itéré) comme format normal.


2 commentaires

docs.djangoproject.com/fr/1.4/topics / Formulaires / Modelforms / ... affiche presque exactement ce dont vous avez besoin. Il suffit de mettre votre requête commandée comme paramètre pour QuerySet


J'ai mon nom dans le projet Django avec Ce correctif :-).


5 Réponses :


3
votes

Merci au commentaire de Rantanplan j'ai trouvé une solution. Je ne pouvais pas utiliser la méthode comme décrit dans le lien ci-dessus parce que je ne sais pas ce que le query va être (il s'agit d'une forme complexe avec des représentation imbriquée).

De toute façon, j'ai trouvé une solution en remplaçant la méthode Get_QuiserySet de la classe de baseinlineCset de Django. Je l'ai copié ci-dessous, y compris mon mod, dans le cas où les googlers le trouvent utiles. xxx


1 commentaires

@ La réponse de Little_birdie ci-dessous est meilleure. Utilisez simplement l'héritage Python pour modifier le requérant qui est renvoyé de la super méthode.



5
votes

Merci à @ John-Peters répondez ci-dessus, pour me faire remarquer dans la bonne direction. Mais voici une meilleure façon:

MyFormset(inlineformset_factory(...)):
    def __init__(self, *args, **kwargs):
        super(MyFormset, self).__init__(*args, **kwargs)
        self.queryset = self.queryset.order_by('myfieldname')


6 commentaires

Vous pouvez obtenir des "duplicats" si votre requérant traite d'une relation M2M. Dans ce cas, il suffit de Pop A .Distion () à la fin du query.


Toutes les chances que vous pouvez donner un exemple de ceci dans un fichier form.py (c'est-à-dire où inlineformset_factory vient?)


Cela ne fonctionne pas si votre objectif est d'avoir les formes vierges supplémentaires entrecoupées parmi les résultats de QuerySet.


@Adambarnes à moins que quelque chose changeait dans des versions plus récentes de Django que je ne connais pas, les lignes Extra doivent toujours être à la fin du modelormset, numériquement. Vous pouvez réorganiser les éléments en JavaScript ou les trier à votre vue avant de les sortir de manière à ce qu'ils apparaissent sur la page dans une commande différente. Mais le format génère toujours le dernier supplément.


@Little_birdie Je crois que vous avez raison - j'ai fini par faire {'formulaires': trié (formsets.Forms, clé = formulaire Lambda: formulaire ["position"])} et et et {% pour la forme sous forme%} (au lieu de {% pour le formulaire en format%} ). Je n'ai pas remarqué des problèmes.


Cela fonctionne .. Mais je pense que ce n'est pas meilleur (pire de quelque manière que ce soit) que de simplement définir ordre_by sur le requérant. Dans certaines de mes représentation de mes constructeurs automatiques, j'ai une colonne comme votre colonne que je commande_by .. Et puis j'utilise jQuery triable de sorte que l'utilisateur puisse déplacer les rangées. (Il y a un peu de JavaScript pour garder la ligne à la largeur correcte pendant qu'ils le glissent de sorte qu'il semble beau) .. Et puis quand ils sont faits, je suis exécuté JavaScript qui renonce à cette colonne dans l'ordre, ils sont affichés .. donc s'ils Enregistrez le formulaire, il enregistre la commande qu'ils l'ont traînée.



6
votes

Si vous n'avez pas défini de formulaire, il s'agit de la version "Code Inline":

FS=inlineformset_factory(ParentClass,ChildClass)
formset=FS(instance=parentobject,
           queryset=parentobject.childobject_set.order_by("-time_begin")
          )


0 commentaires

7
votes

Pour compléter les réponses. Il y a deux façons de contrôler l'ordre des formulaires dans le formulaire: Grésets Respect de l'ordre de QuerySet donné (Ceci est affiché dans d'autres réponses). Une autre solution (si vous souhaitez que l'ordre des formulaires entièrement sous contrôle) est de définir la classe de formsse personnalisée et de remplacer __ iter __ et __ getItem __ méthodes: xxx

Cette approche est décrite dans la documentation Django:

itération sur le format rendra les formes dans l'ordre ont été créés. Vous pouvez changer cette commande en fournissant un autre Mise en œuvre pour le __ iTER __ () méthode.

Les constructeurs automatiques peuvent également être indexés dans, qui renvoie la correspondance. former. Si vous remplacez __ iTER __ , vous devrez également remplacer __ getItem __ avoir un comportement correspondant.

https: / /docs.djangoproject.com/fr/dev/topics/Forms/Formsets/#django.Forms.Formsets.baseformset

L'exemple de mise en œuvre de ces méthodes est par exemple dans ce type de fil: ModelFormset __iter__ Problème de surcharge .


0 commentaires

1
votes

une manière plus simple, mais cela pourrait ne pas s'appliquer dans toutes les situations, mais si vous pouvez vous le permettre, il suffit de définir simplement la commande dans les modèles méta class: xxx

le format respectera la commande requise qui respectera le Valeur de la variable de méta-classe.


0 commentaires