2009-12-29 5 views
1

J'utilise un champ MM/YY personnalisé et un widget basé sur this example. Je veux parcourir les options individuelles du mois et de l'année définies dans la classe du widget afin d'appliquer "selected = 'selected'" à la valeur MM/YY qui correspond à la valeur MM/YY stockée dans la base de données. Cela semble être une manière si désordonnée de faire cela, donc si vous avez de meilleures idées, veuillez les poster ici.Django: parcourir les options dans un champ de sélection personnalisé

class MonthYearWidget(forms.MultiWidget): 
    def __init__(self, attrs=None): 
     months = (
      ('01', 'Jan (01)'), 
      ('02', 'Feb (02)'), 
      ('03', 'Mar (03)'), 
      ('04', 'Apr (04)'), 
      ('05', 'May (05)'), 
      ('06', 'Jun (06)'), 
      ('07', 'Jul (07)'), 
      ('08', 'Aug (08)'), 
      ('09', 'Sep (09)'), 
      ('10', 'Oct (10)'), 
      ('11', 'Nov (11)'), 
      ('12', 'Dec (12)'), 
     ) 

     year = int(datetime.date.today().year) 
     year_digits = range(year, year+10) 
     years = [(year, year) for year in year_digits] 

     widgets = (forms.Select(attrs=attrs, choices=months), forms.Select(attrs=attrs, choices=years)) 
     super(MonthYearWidget, self).__init__(widgets, attrs) 

    def decompress(self, value): 
     if value: 
      return [value.month, value.year] 
     return [None, None] 

    def render(self, name, value, attrs=None): 
     try: 
      value = datetime.date(month=int(value[0]), year=int(value[1]), day=1) 
     except: 
      value = '' 
     return super(MonthYearWidget, self).render(name, value, attrs) 

class MonthYearField(forms.MultiValueField): 
    def __init__(self, *args, **kwargs): 
     forms.MultiValueField.__init__(self, *args, **kwargs) 
     self.fields = (forms.CharField(), forms.CharField(),) 
    def compress(self, data_list): 
     if data_list: 
      return datetime.date(year=int(data_list[1]), month=int(data_list[0]), day=1) 
     return datetime.date.today() 

puis là où je suis coincé, dans le modèle. Je ne peux pas comprendre quel est le nom de la liste itérative pour les mois et les années (s'il y en a un). Trouver que la liste itérative est le problème; Je prévois déjà d'utiliser une instruction ifequal pour déterminer l'option à laquelle "selected = 'selected" doit s'appliquer. J'ai seulement essayé d'itérer au cours des mois jusqu'à présent.

<form action="#" method="POST"> 
{% csrf_token %} 
    <p>{{ form.from_email.label_tag }}: {{ form.from_email }}</p> 
    <p>{{ form.working_month.label_tag }}: 
     <select name="working_month_0" id="id_working_month_0"> 
     {% for i in form.working_month.data_list %} 
      <option value="{{ i }}">{{ option.from_email }}</option> 
     {% endfor %} 
     </select> 
    <p><input type="submit" value="Change Settings Now" /></p> 
</form> 

Merci d'avance pour tous les conseils que vous pouvez tous fournir.

EDIT: Voici la vue générique:

def option_edit(request,option_id): 
    try: 
     option = Option.objects.get(pk=option_id) 
    except Option.DoesNotExist: 
     raise Http404 

    return create_update.update_object(
     request, 
     form_class = OptionForm, 
     template_name = 'options.html', 
     template_object_name = 'option', 
     object_id = option_id, 
     post_save_redirect = '/some/address/' + option_id + '/edit/' 
    ) 

... et la classe de formulaire:

class OptionForm(ModelForm): 
    class Meta: 
     model = Option 
    working_month = MonthYearField(widget=MonthYearWidget) 

Je pense que le modèle est pertinent aussi:

class Option(models.Model): 
    from_email = models.EmailField() 
    working_month = models.DateField() 

Dois-je créer un champ de modèle personnalisé en plus du champ de formulaire personnalisé ou puis-je utiliser cette configuration?

Répondre

2

La magie des formes django est que vous n'avez pas besoin de faire tout cela. En appelant le champ select du formulaire par son nom, il le rendra et sélectionnera la bonne option en fonction des données initiales/d'instance passées dans le formulaire lors de l'instantané.

{{form.working_month}} 

Si vous rencontrez toujours des problèmes, vous pouvez poster la classe de formulaire ainsi?

Bonne chance!

EDIT

En regardant le premier commentaire sur le lien que vous avez publié, cette question est abordée. L'intervenant comprend ce code

def __init__(self, *args, **kwargs): 
    forms.MultiValueField.__init__(self, *args, **kwargs) 
    self.fields = (forms.CharField(), forms.CharField(),) 
+0

Eh bien, le problème est que {{}} form.working_month affiche toujours la première option, Janvier, 2009, même si les données MM/AA actuelles dans la base de données datent d'août 2010. J'ai affiché la vue générique que j'utilise ainsi que la classe de formulaire. Merci. – John

+1

Remplissez-vous le formulaire avec une instance? Si oui, je pense que le problème est avec votre méthode substituée() - en avez-vous besoin? – Tom

+0

Les autres champs de formulaire s'affichent-ils avec les données initiales correctes? – czarchaic

Questions connexes