Re: Bug with model get_*_display() methods?
Thanks for the pointers, that all make sense now. Margie On Aug 8, 6:47 pm, Malcolm Tredinnickwrote: > On Sat, 2009-08-08 at 12:09 -0700, Margie wrote: > > [...] > > > Question: If want to use a special widget for a ChoiceField, is it > > true that I need to instantiate the ChoiceField (or TypedChoiceField), > > rather than just setting the .widget attribute on the one that is by > > default created for me (due to it being a modelForm)? > > > I find that if I just do this: > > > self.fields["status"].widget = StatusWidget(task=instance) > > Grep'ing for "choices" in django/forms/*.py would reveal the answer to > this. Have a look at how the Select widget handles choices, since that > is what you're subclassing. > > The "choices" attribute of all the classes in widgets.py is set in the > __init__() method of each widget. In fields.py, have a look at > ChoiceField and you'll see that when you set choices on a field, they > are also set on the associated widget (there's a _set_choices() method > that is part of the "choices" property on ChoiceField). > > What you're doing in your above code is not setting any choices at all. > You need to tell the widget which choices it can use. > > [...] > > > However, I see when debugging that IntegerField.to_python is an > > unbound method: > > > (Pdb) self.coerce > > > > > What is the right thing to set coerce to if I just want it to do > > whatever it would "normally" do for the corresponding model field if I > > wasn't trying to override the widget? In my case I have verified that > > if I set coerce=int that does work, but that doesn't seem very > > general. I'd much rather use whatever the standard coerce method > > would have been if I hadn't overridden the widget. > > I'm not completely convinced this is a great plan, since if you are only > overriding the widget in __init__, then the coerce function will already > have been set up when the TypedChoiceField was created (it's a feature > of the forms.Field subclass, not the widget). If you are overriding the > form field entirely then you know better than Django what the correct > type to use is, so it's actually easier and arguably clearer to just put > in the right thing. > > However, you also have access to the model, so just use the > model._meta.fields[...] entry for the field and use the to_python() > method on that instance. Look at things like > django.db.models.options.Options.get_field_by_name(). > > Regards, > Malcolm --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Bug with model get_*_display() methods?
Right - of course. Don't ask me why didn't realize to use IntegerField ().to_python myself ... Margie On Aug 8, 12:32 pm, Alex Gaynorwrote: > On Sat, Aug 8, 2009 at 2:09 PM, Margie wrote: > > > Ok, still slightly confused. First - a high level description. I > > have a field that contains choices, but when I display the select, I > > want to display some extra html below the select box, so I am creating > > a custom widget that displays the standard select followed by my html. > > > Question: If want to use a special widget for a ChoiceField, is it > > true that I need to instantiate the ChoiceField (or TypedChoiceField), > > rather than just setting the .widget attribute on the one that is by > > default created for me (due to it being a modelForm)? > > > I find that if I just do this: > > > self.fields["status"].widget = StatusWidget(task=instance) > > > then my widget's select does not contain any choices. My widget > > doesn't do anything special to the select, it looks like this: > > > class StatusWidget(widgets.Select): > > def __init__(self, task, attrs={}): > > self.task = task > > super(StatusWidget, self).__init__(attrs) > > > def render(self, name, value, attrs=None): > > rendered = super(StatusWidget, self).render(name, value, > > attrs) > > rendered = rendered + add a bunch of stuff to the end > > return rendered > > > Because I seem unable to display the choices correctly in the select > > box when I just set the field's widget attribute to my StatusWidget, I > > am instantiating the field itself. That now looks like this: > > > self.fields["status"] = forms.TypedChoiceField > > (choices=Task.STATUS_CHOICES, widget=StatusWidget(task=instance), > > required=False, coerce=IntegerField.to_python) > > > However, I see when debugging that IntegerField.to_python is an > > unbound method: > > > (Pdb) self.coerce > > > > > What is the right thing to set coerce to if I just want it to do > > whatever it would "normally" do for the corresponding model field if I > > wasn't trying to override the widget? In my case I have verified that > > if I set coerce=int that does work, but that doesn't seem very > > general. I'd much rather use whatever the standard coerce method > > would have been if I hadn't overridden the widget. > > > Margie > > > On Aug 8, 12:11 am, Malcolm Tredinnick > > wrote: > >> Hi Margie, > > >> On Fri, 2009-08-07 at 23:17 -0700, Margie wrote: > > >> > Hmmm, ok, after digging around I realize that full_clean was not > >> > setting cleaned_data for the status field to an integer value; > >> > cleaned_data['status'] was just getting set to something like u'1'. > > >> > I am in fact using sqllite, and yes, my status fields are just > >> > integers: > > >> > OPEN_STATUS = 1 > >> > CLOSED_STATUS = 2 > >> > STALLED_STATUS = 3 > > >> > I think the problem has to do with the way I created the status field, > >> > which is like this: > > >> > self.fields["status"] = forms.ChoiceField > >> > (choices=Task.STATUS_CHOICES, widget=StatusWidget(task=instance), > >> > required=False) > > >> Right, that won't do what you want. ChoiceField normalizes to a unicode > >> object. > > >> > I tried moving to TypedChoiceField(), but that didn't help. I > >> > debugged into it in the case where I used TypedChoiceField() and I can > >> > see that when coerce is called it isn't doing anything, it is just > >> > returning the unicode value. > > >> > I find that if I do this instead, that it does do the coerce > >> > correctly: > > >> > self.fields["status"].widget = StatusWidget(task=instance) > > >> > In looking at the doc it looks like the purpose of TypedChoiceField() > >> > is to allow me to create my own coerce function, is that right? > > >> Correct. > > >> > And > >> > of course I wasn't doing that so it was behaving the same as > >> > ChoiceField, and it looks like the default there is to just return the > >> > unicode. > > >> Also correct. The documentation says "Defaults to an identity function" > >> and all the data coming from a form submission are strings (Python > >> unicode objects), so if you don't supply the coerce parameter, it does > >> nothing. > > >> It's probably a slight API wart that TypedChoiceField doesn't just raise > >> an exception if you don't supply coerce(). The default is slightly > >> dangerous, as it almost always means you're misusing the field. Not a > >> fatal flaw in the design, however. > > >> > When I don't declare the status field at all (ie, just let django do > >> > it's default thing), my guess is that it is choosing a coerce function > >> > based on the integer type of my choices, is that true? > > >> Yes. The django.db.models.fields.Field.formfield() method detects if you > >> have specified "choices" in the field and uses the Field subclass's > >> to_python() function as the coerce
Re: Bug with model get_*_display() methods?
On Sat, 2009-08-08 at 12:09 -0700, Margie wrote: [...] > Question: If want to use a special widget for a ChoiceField, is it > true that I need to instantiate the ChoiceField (or TypedChoiceField), > rather than just setting the .widget attribute on the one that is by > default created for me (due to it being a modelForm)? > > I find that if I just do this: > > self.fields["status"].widget = StatusWidget(task=instance) Grep'ing for "choices" in django/forms/*.py would reveal the answer to this. Have a look at how the Select widget handles choices, since that is what you're subclassing. The "choices" attribute of all the classes in widgets.py is set in the __init__() method of each widget. In fields.py, have a look at ChoiceField and you'll see that when you set choices on a field, they are also set on the associated widget (there's a _set_choices() method that is part of the "choices" property on ChoiceField). What you're doing in your above code is not setting any choices at all. You need to tell the widget which choices it can use. [...] > However, I see when debugging that IntegerField.to_python is an > unbound method: > > (Pdb) self.coerce > > > What is the right thing to set coerce to if I just want it to do > whatever it would "normally" do for the corresponding model field if I > wasn't trying to override the widget? In my case I have verified that > if I set coerce=int that does work, but that doesn't seem very > general. I'd much rather use whatever the standard coerce method > would have been if I hadn't overridden the widget. I'm not completely convinced this is a great plan, since if you are only overriding the widget in __init__, then the coerce function will already have been set up when the TypedChoiceField was created (it's a feature of the forms.Field subclass, not the widget). If you are overriding the form field entirely then you know better than Django what the correct type to use is, so it's actually easier and arguably clearer to just put in the right thing. However, you also have access to the model, so just use the model._meta.fields[...] entry for the field and use the to_python() method on that instance. Look at things like django.db.models.options.Options.get_field_by_name(). Regards, Malcolm --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Bug with model get_*_display() methods?
On Sat, Aug 8, 2009 at 2:09 PM, Margiewrote: > > Ok, still slightly confused. First - a high level description. I > have a field that contains choices, but when I display the select, I > want to display some extra html below the select box, so I am creating > a custom widget that displays the standard select followed by my html. > > Question: If want to use a special widget for a ChoiceField, is it > true that I need to instantiate the ChoiceField (or TypedChoiceField), > rather than just setting the .widget attribute on the one that is by > default created for me (due to it being a modelForm)? > > I find that if I just do this: > > self.fields["status"].widget = StatusWidget(task=instance) > > then my widget's select does not contain any choices. My widget > doesn't do anything special to the select, it looks like this: > > class StatusWidget(widgets.Select): > def __init__(self, task, attrs={}): > self.task = task > super(StatusWidget, self).__init__(attrs) > > def render(self, name, value, attrs=None): > rendered = super(StatusWidget, self).render(name, value, > attrs) > rendered = rendered + add a bunch of stuff to the end > return rendered > > Because I seem unable to display the choices correctly in the select > box when I just set the field's widget attribute to my StatusWidget, I > am instantiating the field itself. That now looks like this: > > self.fields["status"] = forms.TypedChoiceField > (choices=Task.STATUS_CHOICES, widget=StatusWidget(task=instance), > required=False, coerce=IntegerField.to_python) > > However, I see when debugging that IntegerField.to_python is an > unbound method: > > (Pdb) self.coerce > > > What is the right thing to set coerce to if I just want it to do > whatever it would "normally" do for the corresponding model field if I > wasn't trying to override the widget? In my case I have verified that > if I set coerce=int that does work, but that doesn't seem very > general. I'd much rather use whatever the standard coerce method > would have been if I hadn't overridden the widget. > > Margie > > > > > On Aug 8, 12:11 am, Malcolm Tredinnick > wrote: >> Hi Margie, >> >> >> >> On Fri, 2009-08-07 at 23:17 -0700, Margie wrote: >> >> > Hmmm, ok, after digging around I realize that full_clean was not >> > setting cleaned_data for the status field to an integer value; >> > cleaned_data['status'] was just getting set to something like u'1'. >> >> > I am in fact using sqllite, and yes, my status fields are just >> > integers: >> >> > OPEN_STATUS = 1 >> > CLOSED_STATUS = 2 >> > STALLED_STATUS = 3 >> >> > I think the problem has to do with the way I created the status field, >> > which is like this: >> >> > self.fields["status"] = forms.ChoiceField >> > (choices=Task.STATUS_CHOICES, widget=StatusWidget(task=instance), >> > required=False) >> >> Right, that won't do what you want. ChoiceField normalizes to a unicode >> object. >> >> >> >> > I tried moving to TypedChoiceField(), but that didn't help. I >> > debugged into it in the case where I used TypedChoiceField() and I can >> > see that when coerce is called it isn't doing anything, it is just >> > returning the unicode value. >> >> > I find that if I do this instead, that it does do the coerce >> > correctly: >> >> > self.fields["status"].widget = StatusWidget(task=instance) >> >> > In looking at the doc it looks like the purpose of TypedChoiceField() >> > is to allow me to create my own coerce function, is that right? >> >> Correct. >> >> > And >> > of course I wasn't doing that so it was behaving the same as >> > ChoiceField, and it looks like the default there is to just return the >> > unicode. >> >> Also correct. The documentation says "Defaults to an identity function" >> and all the data coming from a form submission are strings (Python >> unicode objects), so if you don't supply the coerce parameter, it does >> nothing. >> >> It's probably a slight API wart that TypedChoiceField doesn't just raise >> an exception if you don't supply coerce(). The default is slightly >> dangerous, as it almost always means you're misusing the field. Not a >> fatal flaw in the design, however. >> >> >> >> > When I don't declare the status field at all (ie, just let django do >> > it's default thing), my guess is that it is choosing a coerce function >> > based on the integer type of my choices, is that true? >> >> Yes. The django.db.models.fields.Field.formfield() method detects if you >> have specified "choices" in the field and uses the Field subclass's >> to_python() function as the coerce method. >> >> > I have never >> > used anything but sqlite3 so far, so I guess that was masking the >> > error and I would have run into this in a more serious way when I >> > moved to a different db? >> >> Actually, my SQLite observation was entirely bogus. I suspect what >> you're seeing is the
Re: Bug with model get_*_display() methods?
Ok, still slightly confused. First - a high level description. I have a field that contains choices, but when I display the select, I want to display some extra html below the select box, so I am creating a custom widget that displays the standard select followed by my html. Question: If want to use a special widget for a ChoiceField, is it true that I need to instantiate the ChoiceField (or TypedChoiceField), rather than just setting the .widget attribute on the one that is by default created for me (due to it being a modelForm)? I find that if I just do this: self.fields["status"].widget = StatusWidget(task=instance) then my widget's select does not contain any choices. My widget doesn't do anything special to the select, it looks like this: class StatusWidget(widgets.Select): def __init__(self, task, attrs={}): self.task = task super(StatusWidget, self).__init__(attrs) def render(self, name, value, attrs=None): rendered = super(StatusWidget, self).render(name, value, attrs) rendered = rendered + add a bunch of stuff to the end return rendered Because I seem unable to display the choices correctly in the select box when I just set the field's widget attribute to my StatusWidget, I am instantiating the field itself. That now looks like this: self.fields["status"] = forms.TypedChoiceField (choices=Task.STATUS_CHOICES, widget=StatusWidget(task=instance), required=False, coerce=IntegerField.to_python) However, I see when debugging that IntegerField.to_python is an unbound method: (Pdb) self.coerce What is the right thing to set coerce to if I just want it to do whatever it would "normally" do for the corresponding model field if I wasn't trying to override the widget? In my case I have verified that if I set coerce=int that does work, but that doesn't seem very general. I'd much rather use whatever the standard coerce method would have been if I hadn't overridden the widget. Margie On Aug 8, 12:11 am, Malcolm Tredinnickwrote: > Hi Margie, > > > > On Fri, 2009-08-07 at 23:17 -0700, Margie wrote: > > > Hmmm, ok, after digging around I realize that full_clean was not > > setting cleaned_data for the status field to an integer value; > > cleaned_data['status'] was just getting set to something like u'1'. > > > I am in fact using sqllite, and yes, my status fields are just > > integers: > > > OPEN_STATUS = 1 > > CLOSED_STATUS = 2 > > STALLED_STATUS = 3 > > > I think the problem has to do with the way I created the status field, > > which is like this: > > > self.fields["status"] = forms.ChoiceField > > (choices=Task.STATUS_CHOICES, widget=StatusWidget(task=instance), > > required=False) > > Right, that won't do what you want. ChoiceField normalizes to a unicode > object. > > > > > I tried moving to TypedChoiceField(), but that didn't help. I > > debugged into it in the case where I used TypedChoiceField() and I can > > see that when coerce is called it isn't doing anything, it is just > > returning the unicode value. > > > I find that if I do this instead, that it does do the coerce > > correctly: > > > self.fields["status"].widget = StatusWidget(task=instance) > > > In looking at the doc it looks like the purpose of TypedChoiceField() > > is to allow me to create my own coerce function, is that right? > > Correct. > > > And > > of course I wasn't doing that so it was behaving the same as > > ChoiceField, and it looks like the default there is to just return the > > unicode. > > Also correct. The documentation says "Defaults to an identity function" > and all the data coming from a form submission are strings (Python > unicode objects), so if you don't supply the coerce parameter, it does > nothing. > > It's probably a slight API wart that TypedChoiceField doesn't just raise > an exception if you don't supply coerce(). The default is slightly > dangerous, as it almost always means you're misusing the field. Not a > fatal flaw in the design, however. > > > > > When I don't declare the status field at all (ie, just let django do > > it's default thing), my guess is that it is choosing a coerce function > > based on the integer type of my choices, is that true? > > Yes. The django.db.models.fields.Field.formfield() method detects if you > have specified "choices" in the field and uses the Field subclass's > to_python() function as the coerce method. > > > I have never > > used anything but sqlite3 so far, so I guess that was masking the > > error and I would have run into this in a more serious way when I > > moved to a different db? > > Actually, my SQLite observation was entirely bogus. I suspect what > you're seeing is the difference between these two lines: > > t1 = Task.objects.create(status=u'3') > t2 = Task.objects.get(id=t1.id) > > In this case, t1.status will be a unicode string, but t2.status will > always be an integer, no matter
Re: Bug with model get_*_display() methods?
Hi Margie, On Fri, 2009-08-07 at 23:17 -0700, Margie wrote: > > Hmmm, ok, after digging around I realize that full_clean was not > setting cleaned_data for the status field to an integer value; > cleaned_data['status'] was just getting set to something like u'1'. > > I am in fact using sqllite, and yes, my status fields are just > integers: > > OPEN_STATUS = 1 > CLOSED_STATUS = 2 > STALLED_STATUS = 3 > > I think the problem has to do with the way I created the status field, > which is like this: > > self.fields["status"] = forms.ChoiceField > (choices=Task.STATUS_CHOICES, widget=StatusWidget(task=instance), > required=False) Right, that won't do what you want. ChoiceField normalizes to a unicode object. > > I tried moving to TypedChoiceField(), but that didn't help. I > debugged into it in the case where I used TypedChoiceField() and I can > see that when coerce is called it isn't doing anything, it is just > returning the unicode value. > > I find that if I do this instead, that it does do the coerce > correctly: > > self.fields["status"].widget = StatusWidget(task=instance) > > > In looking at the doc it looks like the purpose of TypedChoiceField() > is to allow me to create my own coerce function, is that right? Correct. > And > of course I wasn't doing that so it was behaving the same as > ChoiceField, and it looks like the default there is to just return the > unicode. Also correct. The documentation says "Defaults to an identity function" and all the data coming from a form submission are strings (Python unicode objects), so if you don't supply the coerce parameter, it does nothing. It's probably a slight API wart that TypedChoiceField doesn't just raise an exception if you don't supply coerce(). The default is slightly dangerous, as it almost always means you're misusing the field. Not a fatal flaw in the design, however. > > When I don't declare the status field at all (ie, just let django do > it's default thing), my guess is that it is choosing a coerce function > based on the integer type of my choices, is that true? Yes. The django.db.models.fields.Field.formfield() method detects if you have specified "choices" in the field and uses the Field subclass's to_python() function as the coerce method. > I have never > used anything but sqlite3 so far, so I guess that was masking the > error and I would have run into this in a more serious way when I > moved to a different db? Actually, my SQLite observation was entirely bogus. I suspect what you're seeing is the difference between these two lines: t1 = Task.objects.create(status=u'3') t2 = Task.objects.get(id=t1.id) In this case, t1.status will be a unicode string, but t2.status will always be an integer, no matter what DB backend is involved. So you are seemingly stumbling over a case like the t1 situation -- where you're using the object after it has been populated and saved, but still using the raw data. I've long argued that allowing the wrong types to be assigned to attributes in Django models is a flaw (Python got rid of automatic type coercion for operator arguments years ago for the same reason), but it's been there forever in Django-years, so isn't going to go away now. Regards, Malcolm --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Bug with model get_*_display() methods?
Hmmm, ok, after digging around I realize that full_clean was not setting cleaned_data for the status field to an integer value; cleaned_data['status'] was just getting set to something like u'1'. I am in fact using sqllite, and yes, my status fields are just integers: OPEN_STATUS = 1 CLOSED_STATUS = 2 STALLED_STATUS = 3 I think the problem has to do with the way I created the status field, which is like this: self.fields["status"] = forms.ChoiceField (choices=Task.STATUS_CHOICES, widget=StatusWidget(task=instance), required=False) I tried moving to TypedChoiceField(), but that didn't help. I debugged into it in the case where I used TypedChoiceField() and I can see that when coerce is called it isn't doing anything, it is just returning the unicode value. I find that if I do this instead, that it does do the coerce correctly: self.fields["status"].widget = StatusWidget(task=instance) In looking at the doc it looks like the purpose of TypedChoiceField() is to allow me to create my own coerce function, is that right? And of course I wasn't doing that so it was behaving the same as ChoiceField, and it looks like the default there is to just return the unicode. When I don't declare the status field at all (ie, just let django do it's default thing), my guess is that it is choosing a coerce function based on the integer type of my choices, is that true? I have never used anything but sqlite3 so far, so I guess that was masking the error and I would have run into this in a more serious way when I moved to a different db? Ok, cool, learn something new every day. Thanks for you pointers, if you can just yay or nay my hypotheses above, that'd be cool. Margie On Aug 7, 7:39 pm, Malcolm Tredinnickwrote: > On Fri, 2009-08-07 at 11:40 -0700, Margie wrote: > > I see inconsistencies in how get_*_display() works based on whether > > the object is a recently saved object. Probably an example describes > > this best: > > > My model contains this: > > > class Task(models.Model): > > > STATUS_CHOICES = ( > > (OPEN_STATUS, 'Open'), > > (CLOSED_STATUS, 'Closed'), > > (STALLED_STATUS, 'Stalled'),) > > > status = models.IntegerField(choices=STATUS_CHOICES, blank=True, > > null=True) > > I'm assuming OPEN_STATUS and friends are integers here (and not '1' or > other strings that contain integers). > > [...] > > > However, if I have recently saved a modelForm associated with my Task > > model and now have a handle to the object that that save() returned, > > the status is in unicode, and get_status_display() doesn't return a > > useful string: > > > (Pdb) type(self) > > > > (Pdb) self.status > > u'3' > > (Pdb) self.get_status_display() > > u'3' > > If I create a standard ModelForm subclass for your task model and then > submit some data to it (just using {"status": "1"} as the POST data > dictionary), I cannot replicate your problem. > > The devil is in the details here. What does your ModelForm look like? > > The results you are seeing are consistent with the form somehow saving a > string value for the "status" field. Which means (a) you're using > SQLite, since other databases will complain about the type mismatch, and > (b) something is going funky in your particular ModelForm. > > The get_FOO_display() method requires an exact match the choice value > and the value of the field, otherwise it just returns the field value. > Since 3 != u'3' in Python, it is returning the correct result, given the > value of the status field. The question is how did you manage to get a > string into the status field. > > Regards, > Malcolm --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Bug with model get_*_display() methods?
On Fri, 2009-08-07 at 11:40 -0700, Margie wrote: > I see inconsistencies in how get_*_display() works based on whether > the object is a recently saved object. Probably an example describes > this best: > > My model contains this: > > class Task(models.Model): > > STATUS_CHOICES = ( > (OPEN_STATUS, 'Open'), > (CLOSED_STATUS, 'Closed'), > (STALLED_STATUS, 'Stalled'),) > > status = models.IntegerField(choices=STATUS_CHOICES, blank=True, > null=True) I'm assuming OPEN_STATUS and friends are integers here (and not '1' or other strings that contain integers). [...] > However, if I have recently saved a modelForm associated with my Task > model and now have a handle to the object that that save() returned, > the status is in unicode, and get_status_display() doesn't return a > useful string: > > (Pdb) type(self) > > (Pdb) self.status > u'3' > (Pdb) self.get_status_display() > u'3' If I create a standard ModelForm subclass for your task model and then submit some data to it (just using {"status": "1"} as the POST data dictionary), I cannot replicate your problem. The devil is in the details here. What does your ModelForm look like? The results you are seeing are consistent with the form somehow saving a string value for the "status" field. Which means (a) you're using SQLite, since other databases will complain about the type mismatch, and (b) something is going funky in your particular ModelForm. The get_FOO_display() method requires an exact match the choice value and the value of the field, otherwise it just returns the field value. Since 3 != u'3' in Python, it is returning the correct result, given the value of the status field. The question is how did you manage to get a string into the status field. Regards, Malcolm --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Bug with model get_*_display() methods?
I see inconsistencies in how get_*_display() works based on whether the object is a recently saved object. Probably an example describes this best: My model contains this: class Task(models.Model): STATUS_CHOICES = ( (OPEN_STATUS, 'Open'), (CLOSED_STATUS, 'Closed'), (STALLED_STATUS, 'Stalled'),) status = models.IntegerField(choices=STATUS_CHOICES, blank=True, null=True) If I get a Task object from the database (via a .get() or .filter()), then my status field contains an integer and I can call the .get_status_display() method, ie: (Pdb) type(t) (Pdb) t.status 3 (Pdb) t.get_status_display() u'Stalled' However, if I have recently saved a modelForm associated with my Task model and now have a handle to the object that that save() returned, the status is in unicode, and get_status_display() doesn't return a useful string: (Pdb) type(self) (Pdb) self.status u'3' (Pdb) self.get_status_display() u'3' Is this expected behavior? Margie --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---