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?
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
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
Les autres champs de formulaire s'affichent-ils avec les données initiales correctes? – czarchaic