J'ai besoin de modifier les données entrantes au formulaire code> avant le nettoyage. Je l'ai fait fonctionner, mais ça a l'air affreux: existe une solution laconique? P> p>
4 Réponses :
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)
Ça marche bien, merci. Mais j'ai lu dans PEP 8 que l'utilisation de est code> ou n'est pas code> avec Aucun code> est meilleur pour le style de code.
Vous avez demandé la solution laconique code>, alors je l'ai raccourcie autant que possible. Dans ce cas, false code> et est Aucun code> a le même effet, dans de nombreuses situations que vous souhaitez uniquement traiter Aucun code> comme Aucun Code>, vous devez donc utiliser est code> pour éviter de penser accidentellement false code> est Aucun code>.
@Yuriy Pep 8 suggère également d'utiliser si args code> au lieu de si len (args)> 0 code> 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) i>.
@Nasmon merci, raccourci. et code> / ou code> au lieu de si code> / sinon code> est un style mauvais et non plus court. Il a également un comportement différent lorsque args [0] code> 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 code> incluront l'élément mis à jour.
J'ai essayé et effectivement les valeurs de Data CODE> sont les conditions attendues, mais à la fin, le modelform code> utilise les données initiales. Ensuite, j'ai testé ce cas: >> A = [1, 2] code> >> B = A [0] code> >> B = 2 code> Quand J'ai appelé a code> elle n'a pas retourné [2, 2] code>. La solution d'Alasdair envoie explicitement data code> à super () code> et le résultat est ok. Existe-t-il un moyen de définir la valeur de B code> et de définir réellement la valeur de A [0] code>?
@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'}] code>
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) code>, la requête requête.post code> est immuable, vous ne pouvez donc pas modifier en place. Dans ma réponse, je fais data = data.copy () code> 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.
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 __ code> 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). p>
J'ai trouvé une autre solution: upd upd: correction d'erreur: UPD: semble toujours avoir des problèmes et ne pas fonctionner correctement. p> p> super (auto . P>
faire DATA CODE> Le premier argument de la méthode __ init __ code>, identique au formulaire de super classe code>. De cette façon, vous n'avez pas à creuser dans args code> ou kwargs code>.
Dans Django 1.11, je reçois l'erreur suivante: super () .__ init __ (données = données, * args, ** kwargs) code> 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 CODE> font partie de la ligne Super () CODE> La ligne provoque l'erreur. Les œuvres suivantes: super (tagform, auto) .__ init __ (données, * args, ** kwargs) code>
Dans une nouvelle installation de Django, j'ai enregistré un modèle avec un charfield code> dans l'administrateur et j'ai joint le formulaire suivant: MyModelform (formulaires.modelform): code> def __init __ (auto, données = Aucune, * args, ** kwargs): code> super () .__ init __ (données = données, * args, ** kwargs) code>. Il donne l'erreur lorsque je saisis une lettre aléatoire et appuyez sur Enregistrer code>.
@Raratiru tu as raison. Le Django Admin passe request.files code> comme argument, nous devons donc modifier data code> vers un argument de position pour éviter le typeError code>. J'ai mis à jour la réponse comme vous l'avez suggéré.