On Aug 21, 2:49 pm, Glenbot <[email protected]> wrote:
> I ran into something weird in Django and i'm completely stumped. I got
> it to work but i'm trying to understand the logic behind it.
>
> I have the following data model:
>
> from django.db import models
>
> class Setting(models.Model):
>     name  = models.CharField(max_length=200)
>     value = models.TextField()
>
>     class Meta:
>         db_table = "t_settings"
>
>     def __unicode__(self):
>         return self.name
>
> I have the following form model:
>
> from django import forms
>
> class GlobalSettingsForm(forms.Form):
>     # specify all the variables here
>     site_name = forms.CharField(required=True,
>                                 max_length=200,
>                                 label="Site Name",
>                                 help_text="What you want your site to
> be called company name, personal name, etc."
>                                 )
>
>     site_tagline = forms.CharField(required=False,
>                                    max_length=200,
>                                    label="Site Tagline",
>                                    help_text="A quick tag line on what
> your site is about")
>
>     site_url = forms.URLField(required=True,
>                               label="Site URL",
>                               max_length=200,
>                               help_text="All links that reference your
> site will use this url. I would not change this unless you are super
> sure." )
>
> From the shell I have the following code to create the form:
>
> form = GlobalSettingsForm(data={'site_name':'test','site_url':'http://
> localhost/','site_tagline':'test'})
>
> Running a type on form i get: <class
> 't_settings.forms.GlobalSettingsForm'> , perfect so far...
>
> next I call form.is_valid() to get the cleaned_data attribute and all
> is good.
>
> form.cleaned_data returns {'site_name': u'test', 'site_tagline':
> u'test', 'site_url': u'http://localhost/'} as expected
>
> now i want to change the information in the database so I loop through
> cleaned_data, grab the object, and save:
>
> for item in form.cleaned_data:
>     setting = Setting.objects.filter(name=item)
>     setting[0].value = form.cleaned_data[item]
>     setting[0].save()
>
> but it does not work. setting[0].value = form.cleaned_data[item] fails
> to assign the data
>
> if i run it like this it works:
>
> for item in form.cleaned_data:
>     setting = Setting.objects.get(name__exact=item)
>     setting.value = form.cleaned_data[item]
>     setting.save()
>
> all i did was change the method used from filter to get, why does one
> work and not the other??
>
> if i create the objects individually and equate them they are the
> same:
> setting = Setting.objects.get(name__exact=item)
> setting2 = Setting.objects.filter(name=item)
>
> setting2[0] == setting it equals True
> type(setting2[0]) == setting it equals True
>
> Also I am using, Django 1.1 with MySql Python...
>
> Stumped.

The difference isn't between filter() and get() so much as it is
between having a specific instance and an index into a queryset.

Django's model instances are just that, instances. There's no identity
between different objects, even if they refer to the same database
row. And each time you slice a queryset, to get an individual
instance, you get a *different* object.

To see this, try getting two objects with the same index from the same
queryset:

>>> settings = Setting.objects.filter(name=item)
>>> setting0_1 = settings[0]
>>> setting0_2 = settings[0]
>>> # both refer to the same db row, but are *not* the same instance
>>> setting0_1 is setting0_2
False

You can also call id() on setting0_1 and setting0_2 to see that their
internal representations are not the same.

To fix this in your code, you just need to store the sliced object in
a variable:

for item in form.cleaned_data:
    setting = Setting.objects.filter(name=item)[0]
    setting.value = form.cleaned_data[item]
    setting.save()

ie instead of calling setting[0] each time, get the actual setting
once, and keep a reference to it.

--
DR.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to