8
votes

Champ de Django personnalisé pour stocker une liste d'adresses électroniques

J'essaie d'ajouter un champ à un modèle Django qui représentera une liste des adresses électroniques. J'aimerais qu'un utilisateur entrait une liste d'adresses séparées par des virgules dans un formulaire dans l'administrateur, que mon application analyse alors pour envoyer une série d'emails.

Ma mise en œuvre actuelle couvre l'idée de base, mais a une limitation significative. . Dans l'administrateur, si je saisis une chaîne comme foo@example.com, bar@example.com.com code>, alors il écrit correctement cela à la base de données comme [u'foo@exemple.com ' , u'bar@example.com '] code>. Mais l'administrateur affiche cette valeur sérialisée au lieu de la chaîne humanisée. Plus important encore, si je modifie et sauvegardez l'enregistrement, sans modifier, la même conversion change [u'foo@example.com ', u'bar@example.com'] code> to [u "[u'foo@example.com '", u "u'bar@example.com']"] "] code>. p>

Comment convertir la représentation de la liste Python à un chaîne à utiliser dans l'administrateur? Est-ce le but de la méthode valse_to_string code> ou dois-je faire la conversion quelque part d'autre? P>

Mon champ modèle personnalisé actuel est le suivant: P>

class EmailListField(models.TextField):
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        if not value:
            return
        if isinstance(value, list):
            return value
        return [address.strip() for address in value.split(',')]

    def get_db_prep_value(self, value):
        if not value:
            return
        return ','.join(unicode(s) for s in value)

    def value_to_string(self, obj):
        value = self._get_val_from_obj(obj)
        return self.get_db_prep_value(value)


2 commentaires

Cela doit-il être une liste ressemblerait à la liste séparée des virgules dans l'exemple Docs - docs.djangoproject.com/fr/dev/ref/forms/validation/... travail?


Merci, mais cet exemple est pour un champ de formulaire, de valider l'entrée d'un utilisateur. Ce dont j'ai besoin est un champ modèle, pour enregistrer plusieurs adresses à la base de données.


4 Réponses :


3
votes

Je ne ferais pas ça. Je ferais tout ce que votre emaillistfield est censé être associé à être un à plusieurs avec des champs d'adresses électroniques.


5 commentaires

Je vois comment cela est plus simple, mais ces adresses électroniques ne sont pas réellement liées à d'autres données de mon application. Est-il logique d'introduire une nouvelle table e-mail_address à la base de données, juste pour contenir une colonne?


Oui, c'est la meilleure façon. Cela aidera également d'une autre manière, comme la recherche, etc.


Dois être d'accord avec Zsquare. C'est la façon judicieuse de le faire. Vous voudrez peut-être aussi consulter le gestionnaire Admin.Tabularinline de Django afin que votre application d'administration puisse afficher la liste des e-mails «en ligne» avec l'objet de profil (ou quoi que ce soit, vous vous attendez à associer Emaillistfield avec).


Et utilisez la validation de Django Emailfield!


D'accord alors, je vais essayer cette approche à la place. Merci à tout le monde pour me donner droit.



3
votes

La question est morte, mais vous pouvez le faire en ajoutant la présentation particulière à votre Python Val xxx


0 commentaires

2
votes

i basé cela hors des documents mais c'est un champ de modèle à la place:

class MultiEmailField(models.TextField):

    def to_python(self, value):

        if not value:
            return None  # []

        cleaned_email_list = list()
        #email_list = filter(None, value.split(','))
        email_list = filter(None, re.split(r';|,\s|\n', value))

        for email in email_list:
            if email.strip(' @;,'):
                cleaned_email_list.append(email.strip(' @;,'))

        print cleaned_email_list
        cleaned_email_list = list(set(cleaned_email_list))

        return ", ".join(cleaned_email_list)

    def validate(self, value, model_instance):
        """Check if value consists only of valid emails."""

        # Use the parent's handling of required fields, etc.
        super(MultiEmailField, self).validate(value, model_instance)

        email_list = value.split(',')

        for email in email_list:
            validate_email(email.strip())


2 commentaires

Avec cette approche si vous avez 1 courrier électronique valide et 1 courrier électronique non valide, le courrier électronique valide ne sera pas retourné.


C'est un champ multi-e-mail, de sorte que toutes les entrées doivent être valides ou la validation devraient échouer.



1
votes

Suivant est le champ modèle avec validation de chaque courrier électronique et une manipulation correcte de l'administration. Basé sur les réponses d'Evilnan et d'Andrewf. XXX


0 commentaires