0

I am writing a web app that displays user profiles.

The profile includes a display of the user's interest in other users, which can be uni- or bidirectional. I am using django's included User model to handle authentication and authorization.

The problem I have is that under some circumstances the rendered pages present data from queries executed earlier. Specifically, this happens when I am using the app as two different users on the same computer but on different browsers (Chrome and Safari on OS X; using the django development web server). Right after I load a page for user 1, if I reload a page for user 2 I see user 1's query results.

I have confirmed that my queries are correct by printing them to the console. I think the problem may be at the web server, because the pages load the right queries right after a server restart.

Any ideas?

** Edit: as Daniel points out, the problem is that the interest_view function has a dictionary as a default parameter.**


Relevant code snippets:

models.py

class Profile(UserenaBaseProfile):
    user = models.OneToOneField(User, unique=True)

class Interest(models.Model):
    user = models.ForeignKey(User, related_name=u'interests')
    interest = models.ForeignKey(User)

views.py

from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext

def interest_view(request, username, extra_context={}):
    user = get_object_or_404(User, username__iexact=username)

    profile = user.get_profile()
    if not profile.can_view_profile(request.user):
        return HttpResponseForbidden("You can't view this page.")

    interests = Interest.objects.filter(user=user)
    if len(interests) > 0:
        extra_context['active_interests'] = interests

    return render_to_response('interest_detail.html',
                              extra_context,
                              context_instance=RequestContext(request)
    )

interest_detail.html

{% if active_interests %}
    {% for interest in active_interests %}
        <li>
            {{ interest.interest.first_name }} {{ interest.interest.last_name }}
        </li>
    {% endfor %}
{% endif %}
edsv
  • 62
  • 4
  • could you post the relevant parts of your views, models and settings (caching enabled? as David Pursehouse pointed out)? – tback Aug 28 '12 at 08:26
  • Do you have caching enabled? I've seen that cause unexpected results in rendered templates. – David Pursehouse Aug 28 '12 at 08:05
  • I'm not using any caching framework. But the behavior is exactly _as if_ I weren't marking the dirty bits of the cache when it changes. – edsv Aug 28 '12 at 08:11
  • @tback: I've posted relevant code for your perusal. – edsv Aug 28 '12 at 18:43

1 Answers1

2

You haven't shown any code, so this is impossible to debug. But the issue is almost certainly that you are defining queries at module level, where they persist for the lifetime of the process (which is many requests).

Edit:

Well, I was almost right - it is an issue with things being defined at module level, although in your case it's the Python default argument gotcha. See the effbot for a great explanation, although the default SO question on this is one: Least astonishment in Python.

Community
  • 1
  • 1
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thanks for the suggestion. Can you take a look at the code I posted and let me know if you think my query is being executed at the module level? As I said, if I print `interests` to the console, I can see that the query is executing correctly upon calling the `interest_detail` view. – edsv Aug 28 '12 at 18:40