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
-~----------~----~----~----~------~----~------~--~---