Hi all,

Last week I ported a site that gets 50k+ pageviews/day from a PHP/
mySQL stack to Django/Postgresql. It has gone mostly smoothly, all
things considered. However, I have encountered a VERY troubling bug
involving the forms module, and I can't figure it out.

The form in question allows users to edit their profile. We have
several types of users, and each user type has a core set of fields,
as well as a few unique ones. Rather than write each profile edit form
from scratch, they inherit from parent classes.

The profile edit form accepts a User instance in its __init__ method,
and uses that object to populate the initial data, and also to save
the cleaned data to the appropriate User and UserProfile instances.

The problem is in about 20% of the time, the form, when displayed on a
page, is displaying OTHER users' information as the initial data. I
have determined that this is not a page caching issue. Additionally, I
confirmed that the correct user object is being passed to the form
class. So the form instance itself is switching the user object. My
guess is that somehow the user object is being assigned as a class
attribute, not an instance attribute. But otherwise I am stumped.

Here are snippets of the code. I know the inheritance scheme seems a
bit convoluted, but it was written this way in the name of DRY. Any
help would be greatly appreciated.

Leif

#####################

class PostalCodeForm (forms.Form):
        country = forms.ChoiceField(choices=[(c.country_code,c.en_name) for c
in Country.objects.all()],required=True, label='Country')
        postal_code = forms.CharField(required=True, label="ZIP/postal code")

        def clean_country (self):
                ...

        def clean_postal_code (self):
                ...
####

class UserProfileEditFormBase (forms.Form):
        first_name = custom_fields.NoProfanitiesCharField(max_length=150,
help_text = 'Your real first name. We will keep it private.')
        last_name = custom_fields.NoProfanitiesCharField(max_length=150,
required=False, help_text = 'Your real last name. We will keep it
private.')
        display_name = custom_fields.NoProfanitiesCharField(max_length=40,
help_text="Your public screenname. Will be shown on reviews that you
write, comments, etc.", label="Display name")
        email = custom_fields.EmailField()
        gender = forms.models.ModelChoiceField(queryset=Gender.objects.all(),
empty_label=None)

        def __init__ (self, user, *args, **kwargs):
                kwargs.setdefault('initial',{})
                kwargs['initial'] = self.get_initial(user,kwargs['initial'])
                super(UserProfileEditFormBase,self).__init__(*args, **kwargs)
                self.user = user

        def get_initial (self, user, initial={}):
                for k in self.base_fields.keys():
                        if k=='country':
                                initial[k] = getattr(profile,k).country_code
                        elif k=='postal_code' and getattr(profile,k,None):
                                initial[k] = getattr(profile,k).postal_code
                        elif getattr(user,k,None):
                                initial[k] = getattr(user,k)
                        elif getattr(profile, k, None):
                                a = getattr(profile, k)
                                if hasattr(a,'id'):
                                        initial[k] = a.id
                                else:
                                        initial[k] = a
                return initial

        def save (self):
                # uses self.user to save the cleaned_data
                ...

##########

class UserProfileEditForm (UserProfileEditFormBase, PostalCodeForm):

        about_you = forms.CharField(help_text="Description of yourself that
will appear with reviews and comments that you write.",
widget=forms.widgets.Textarea, required=False )

        def get_initial (self, user, initial={}):

                initial = super(UserProfileEditForm,self).get_initial(user, 
initial)
                bios = user.reviewerbio_set.filter(is_primary=True)
                if bios:
                        initial['about_you'] = bios[0].text

                return initial

        def save (self, user):
                ....

###############


-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@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.

Reply via email to