7
votes

Modifier les données entrantes à la forme Django avant de nettoyer

J'ai besoin de modifier les données entrantes au formulaire avant le nettoyage. Je l'ai fait fonctionner, mais ça a l'air affreux: xxx

existe une solution laconique?


0 commentaires

4 Réponses :


5
votes

Vous pouvez compresser le si code> / elif code> / sinon code> sur une ligne suffisamment facilement:

def __init__(self, *args, **kwargs):
    data = args[0] if args else kwargs.get('data', None)
    if data:
        data['content'] = ' '.join(data['content'].strip().split())
    super(TagForm, self).__init__(*args, **kwargs)


13 commentaires

Ça marche bien, merci. Mais j'ai lu dans PEP 8 que l'utilisation de est ou n'est pas avec Aucun est meilleur pour le style de code.


Vous avez demandé la solution laconique , alors je l'ai raccourcie autant que possible. Dans ce cas, false et est Aucun a le même effet, dans de nombreuses situations que vous souhaitez uniquement traiter Aucun comme Aucun , vous devez donc utiliser est pour éviter de penser accidentellement false est Aucun .


@Yuriy Pep 8 suggère également d'utiliser si args au lieu de si len (args)> 0 dans votre code d'origine, qui utilise le fait que les séquences vides sont fausses.


Les «données» doivent être entourées de citations à l'intérieur de la déclaration IF. Pour que cela soit encore plus court, vous pouvez utiliser data = args et args [0] ou kwargs.get ("données", aucune) .


@Nasmon merci, raccourci. et / ou au lieu de si / sinon est un style mauvais et non plus court. Il a également un comportement différent lorsque args [0] est faux.


Techniquement, cela fonctionne bien, mais les données modifiées ne sont pas transmises à Super et le formulaire conserve les anciennes données.


@RarAriRU Que voulez-vous dire? Nous modifions les données en place, donc les args passés à Super incluront l'élément mis à jour.


J'ai essayé et effectivement les valeurs de Data sont les conditions attendues, mais à la fin, le modelform utilise les données initiales. Ensuite, j'ai testé ce cas: >> A = [1, 2] >> B = A [0] >> B = 2 Quand J'ai appelé a elle n'a pas retourné [2, 2] . La solution d'Alasdair envoie explicitement data à super () et le résultat est ok. Existe-t-il un moyen de définir la valeur de B et de définir réellement la valeur de A [0] ?


@Raratiru qui n'est pas équivalent. Vous ne manipulez que des noms, ne mutant pas réellement des objets. Voici ce qui se passe réellement: >>> args = [{"contenu": "foo"}] >>> Data = args [0] >>> Data ["Contenu"] = "bar" >> > args [{'content': 'bar'}]


Ok, c'est évident. Cela devait être allé quelque chose d'autre mal et je me suis confus. Merci de toute façon pour la clarification.


Pour le cas d'utilisation typique, formulaire = MyForm (demande.post) , la requête requête.post est immuable, vous ne pouvez donc pas modifier en place. Dans ma réponse, je fais data = data.copy () pour obtenir un requérant mutable.


@Alasdair Merci alors, c'est la raison pour laquelle cette solution ne fonctionnait pas quand je l'ai mise en œuvre.


@Alasdair je suis un peu confus. Je n'ai pas utilisé Django depuis des années, je ne peux donc pas facilement tester cela. Mais si l'objet est immuable, cela ne ferait-il pas d'exception? Ce que Raratiru décrit est-il en silence.



0
votes

Comme indiqué dans le Documentation pour la validation de formulaire et de champ vous ne peut pas le faire sous forme de forme, de sorte que la méthode __ init __ semble la manière la plus légitime. Vous pouvez bien sûr également modifier les données avant de le transmettre au formulaire (par exemple à votre vue ou où vous traitez le formulaire).


0 commentaires

2
votes

J'ai trouvé une autre solution: xxx

upd upd: correction d'erreur: super (auto .

UPD: semble toujours avoir des problèmes et ne pas fonctionner correctement.


0 commentaires

7
votes

faire DATA Le premier argument de la méthode __ init __ , identique au formulaire de super classe . De cette façon, vous n'avez pas à creuser dans args ou kwargs . xxx


6 commentaires

Dans Django 1.11, je reçois l'erreur suivante: super () .__ init __ (données = données, * args, ** kwargs) typeError: __init __ () a eu plusieurs valeurs pour argument 'Data' < / code>


@RarAratiu Ce n'est pas assez d'informations pour pouvoir vous aider, veuillez poser une nouvelle question.


En effet, c'est un très vieux poste de toute façon, merci d'avoir répondu.


Je l'ai trouvé! Les données = DATA font partie de la ligne Super () La ligne provoque l'erreur. Les œuvres suivantes: super (tagform, auto) .__ init __ (données, * args, ** kwargs)


Dans une nouvelle installation de Django, j'ai enregistré un modèle avec un charfield dans l'administrateur et j'ai joint le formulaire suivant: MyModelform (formulaires.modelform): def __init __ (auto, données = Aucune, * args, ** kwargs): super () .__ init __ (données = données, * args, ** kwargs) . Il donne l'erreur lorsque je saisis une lettre aléatoire et appuyez sur Enregistrer .


@Raratiru tu as raison. Le Django Admin passe request.files comme argument, nous devons donc modifier data vers un argument de position pour éviter le typeError . J'ai mis à jour la réponse comme vous l'avez suggéré.