82 votes

Personnaliser / supprimer l'option vierge de la case de sélection Django

Je suis l'aide de Django 1.0.2. J'ai écrit un ModelForm soutenu par un Modèle. Ce modèle a une ForeignKey où vide=False. Lorsque Django génère du code HTML de cette forme, il crée une zone de sélection, avec une option pour chaque ligne dans la table référencée par la clé etrangère. Il crée également une option en haut de la liste qui n'a pas de valeur et s'affiche comme une série de tirets:

<option value="">---------</option>

Ce que j'aimerais savoir, c'est:

  1. Quelle est la façon la plus propre pour enlever cette auto-généré option dans la boîte de sélection?
  2. Quelle est la façon la plus propre de le personnaliser pour qu'il montre que:

    <option value="">Select Item</option>
    

En cherchant une solution, je suis tombé sur Django billet 4653 qui m'a donné l'impression que les autres avaient la même question, et que le comportement par défaut de Django peut avoir été modifié. Ce billet est de plus d'un an donc j'espérais qu'il pourrait être le moyen le plus propre pour accomplir ces choses.

Merci pour toute aide,

Jeff

Edit: j'ai configuré le champ ForeignKey en tant que tel:

verb = models.ForeignKey(Verb, blank=False, default=get_default_verb)

Ce n'est, par défaut, de sorte qu'il n'est plus le vide/tirets option, mais malheureusement, il ne semble pas résoudre les problèmes de mes questions. C'est le vide/tirets option apparaît toujours dans la liste.

96voto

Carl Meyer Points 30736

N'ai pas testé, mais basée sur la lecture de Django reinhardt, le code ici et ici, je crois que cela devrait fonctionner:

class ThingForm(models.ModelForm):
  class Meta:
    model = Thing

  def __init__(self, *args, **kwargs):
    super(ThingForm, self).__init__(*args, **kwargs)
    self.fields['verb'].empty_label = None

EDIT: C'est documenté, bien que cela ne soit pas nécessairement savoir rechercher ModelChoiceField si vous travaillez avec un auto-généré ModelForm.

EDIT: Comme jlpp notes, dans sa réponse, ce n'est pas complète - que vous avez à ré-attribuer le choix pour les widgets, après modification de la empty_label attribut. Puisque c'est un très orthodoxe, l'autre option qui pourrait être plus facile à comprendre, c'est juste primordial de l'ensemble de la ModelChoiceField:

class ThingForm(models.ModelForm):
  verb = ModelChoiceField(Verb.objects.all(), empty_label=None)

  class Meta:
    model = Thing

39voto

zalew Points 4213

des docs

Le choix vide ne sera pas inclus si le champ du modèle a vide = False et une valeur implicite par défaut (la valeur par défaut sera initialement sélectionnée à la place).

alors définissez la valeur par défaut et vous êtes ok

24voto

jlpp Points 692

Avec Carl de répondre en tant que guide et après l'enracinement autour de Django source pour un couple d'heures, je pense que c'est une solution complète:

  1. Pour supprimer l'option vide (extension de Carl exemple):

    class ThingForm(models.ModelForm):
      class Meta:
        model = Thing
    
    
      def __init__(self, *args, **kwargs):
        super(ThingForm, self).__init__(*args, **kwargs)
        self.fields['verb'].empty_label = None
        # following line needed to refresh widget copy of choice list
        self.fields['verb'].widget.choices =
          self.fields['verb'].choices
    
  2. Pour personnaliser l'option "vide" de l'étiquette est essentiellement le même:

    class ThingForm(models.ModelForm):
      class Meta:
        model = Thing
    
    
      def __init__(self, *args, **kwargs):
        super(ThingForm, self).__init__(*args, **kwargs)
        self.fields['verb'].empty_label = "Select a Verb"
        # following line needed to refresh widget copy of choice list
        self.fields['verb'].widget.choices =
          self.fields['verb'].choices
    

Je pense que cette approche s'applique à tous les scénarios où ModelChoiceFields sont rendus au format HTML, mais je ne suis pas positif. J'ai constaté que lorsque ces champs sont initialisés, leurs choix sont transmis à l'widget de sélection (voir django.les formulaires.champs.ChoiceField._set_choices). Réglage de la empty_label après l'initialisation n'actualise pas le widget de sélection de la liste de choix. Je ne suis pas assez familier avec Django de savoir si cela devrait être considéré comme un bug.

21voto

Lu.nemec Points 53

Vous pouvez utiliser ceci sur votre modèle:

 class MyModel(models.Model):
    name = CharField('fieldname', max_length=10, default=None)
 

défaut = Aucun est la réponse: D

NOTE: j'ai essayé ceci sur Django 1.7

8voto

ykhrustalev Points 142

Comme pour le django 1.4, tout ce dont vous avez besoin est de définir la valeur "par défaut" et "blank = False" dans le champ choice

 class MyModel(models.Model):
    CHOICES = (
        (0, 'A'), 
        (1, 'B'),
    )
    choice_field = models.IntegerField(choices=CHOICES, blank=False, default=0)
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X