Champs auto-tronqués à longueur maximale dans les champs de Django

j'ai un champ qui a un max_length définir. Quand je sauve une instance model, et que la valeur du champ est supérieure à max_length, Django enforce that max_length au niveau base de données. (Voir Django docs sur les modèles: http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.CharField.max_length)

cependant, puisque J'utilise Postgres, je reçois un DatabaseError exception comme ceci:

DatabaseError: value too long for type character varying(1000)

je préfère à la place de l'auto-tronquer la valeur (donc je n'ont pas une exception). Maintenant, je peux le faire manuellement, mais ce que je voudrais vraiment c'est que tous mes modèles tronquent automatiquement la valeur. (Pas nécessairement intelligemment. Le couper juste au 999ème personnage est très bien.)

devrais-je juste écrire une classe personnalisée qui importe des modèles.Modéliser et outrepasser la méthode save (), en boucle à travers chaque _meta.field, je vérifie la force maximale, et puis je tronque? Cela semble inélégant et il doit y avoir un meilleur moyen.

22
demandé sur Samuel Clay 2010-08-11 19:10:19

4 réponses

vous pouvez créer un champ personnalisé qui AUTO-tronque le champ (je pense que ce code devrait fonctionner, mais revérifiez-le):

class TruncatingCharField(models.CharField):
    def get_prep_value(self, value):
        value = super(TruncatingCharField,self).get_prep_value(value)
        if value:
            return value[:self.max_length]
        return value

Alors, au lieu d'utiliser models.CharField dans votre models.py file, il suffit D'utiliser TruncatingCharField à la place.

get_prep_value prépare la valeur pour un champ à insérer dans la base de données, donc c'est l'endroit idéal pour tronquer.

31
répondu Jordan Reiter 2010-08-11 17:07:47

pourquoi n'utilisez-vous pas un champ de texte? Dans le manuel:

Pour de grandes quantités de texte, utilisation TextField.

3
répondu Frank Heikens 2010-08-11 15:56:40

Pourquoi ne pas utiliser ModelForm. ModelForm renforce une validation, en définissant sa valeur par défaut max_length à la propriété max_length du champ model, et en soulevant une erreur de validation appropriée quand form.is_valid() est appelée. De cette façon, vous n'avez pas à enregistrer le formulaire, jusqu'à ce que le formulaire est validé.

Ou, si vous voulez passent silencieusement la validation et de tronquer convient le mieux pour vous, d'écrire une simple django forme, et écrire une propre méthode qui tronque la chaîne d'entrée à l'max_length et retour dépouillé de données. Prendre des données à partir de form.cleaned_data après la validation du formulaire et la sauvegarde de l'objet.

tout compte fait, les formulaires sont conçus pour valider les données avant D'aller au DB.

3
répondu simplyharsh 2011-06-29 11:17:29

cela semble inélégant et il doit y avoir une meilleure façon.

la seule raison pour laquelle le comportement tronqué se produit en premier lieu est à cause de L'échec de MySQL à adhérer à la norme SQL. Le lancer d'une exception est la réponse correcte lorsque l'on tente d'insérer une chaîne dans un champ VARCHAR qui n'est pas assez large pour le tenir. MySQL tronque et insère à la place.

si vous voulez corrompre vos données en silence, alors vous devrez le faire manuellement d'une façon ou d'une autre -- PostgreSQL ne le fera jamais pour vous.

-2
répondu Matthew Wood 2010-08-11 18:37:45