Hello,

I am trying to implement a cache system using the post_save signal.
The problem is the code below, a Thread subclass that ends up calling
run(), the cache database never runs. It's driving me crazy!!! Is
there something going on with the way Django cache's queries which is
what I expect? Can I turn this off? This is the Thread subclass code
is below.

What I am trying to do is implement a staticpages app which is much
like flatpages but it adds a menu foreign key to what is basically a
flatpage. I am trying to make a cache system whereby when a user saves
a link or a menu, the below code rebuilds the XHTML to use in the
staticpage Context.

Here is a sample run:

1) I am in the admin and change a menu to consist of a title called
"Cool Sites 222" and three links
2) post_save runs and here is what is supposed to be saved in the
database (a print is called in my code:
Menu 2
<div id="">
  <h3>Cool Sites 222</h3>
  <ul>
   <li><a title="Google Inc" href="http://www.google.com/";>Google Inc</
a></li>

<li><a title="Microsoft" href="http://www.microsoft.com";>Microsoft</
a></li>

<li><a title="Ryan Kaskel" href="http://www.ryankaskel.com";>Ryan
Kaskel</a></li>

<li><a title="Yahoo! Inc" href="http://www.yahoo.com";>Yahoo Homepage</
a></li>


  </ul>
</div>

If I don't change anything in the menu, eventually it gets the right
XHTML and prints it

3) The cached XHTML in the database is never changed and still
contains the information from its creation.

I think this is a bug because the following this code:

    def _cache_menu(self, menu, xhtml):
        """
        Stores xhtml into the CachedMenuXhtml table where the row's
menu matches
        the menu_obj.
        """
        if menu and xhtml:
            cm = self.CachedMenuXhtml.objects.filter(menu__exact=menu)
            if cm[0]:
                print cm[0].xhtml
                cm[0].xhtml = xhtml
                cm[0].save()
                print cm[0].xhtml
                print xhtml
            else:
                new_cm = self.CachedMenuXhtml(menu=menu,xhtml=xhtml)
                new_cm.save()

produces...

<div id="">
  <h3>Cool Sites</h3>
  <ul>
   <li><a title="Microsoft" href="http://www.microsoft.com";>Microsoft</
a></li>

<li><a title="Ryan Kaskel" href="http://www.ryankaskel.com";>Ryan
Kaskel</a></li>

<li><a title="Yahoo! Inc" href="http://www.yahoo.com";>Yahoo Homepage</
a></li>


  </ul>
</div>


[11/Jul/2009 05:03:47] "POST /admin/staticpages/menu/2/ HTTP/1.1" 302
0
<div id="">
  <h3>Cool Sites</h3>
  <ul>
   <li><a title="Microsoft" href="http://www.microsoft.com";>Microsoft</
a></li>

<li><a title="Ryan Kaskel" href="http://www.ryankaskel.com";>Ryan
Kaskel</a></li>

<li><a title="Yahoo! Inc" href="http://www.yahoo.com";>Yahoo Homepage</
a></li>


  </ul>
</div>


<div id="">
  <h3>Cool Sites 222</h3>
  <ul>
   <li><a title="Google Inc" href="http://www.google.com/";>Google Inc</
a></li>

<li><a title="Microsoft" href="http://www.microsoft.com";>Microsoft</
a></li>

<li><a title="Ryan Kaskel" href="http://www.ryankaskel.com";>Ryan
Kaskel</a></li>

<li><a title="Yahoo! Inc" href="http://www.yahoo.com";>Yahoo Homepage</
a></li>


  </ul>
</div>
--------------------
CODE for Thread subclass that post_save signal calls

# Signlas for caching of menu XHTML

import threading

from django.template.loader import get_template
from django.template import Context
from django.utils.safestring import mark_safe
from django.core.exceptions import ObjectDoesNotExist

from asqcom.apps.staticpages.settings import STATICPAGE_TEMPLATE,
MENU_TEMPLATE
from asqcom.apps.staticpages.settings import LINK_TEMPLATE,
MENU_CSS_ID

class GenerateMenuXhtml(threading.Thread):
    """
    Subclasses a threading.Thread class to generate a menu's XHTML in
a separate
    thread. All Link objects that have this menu associated with it
are gathered
    and combined in an XHTML unordered list.

    If the sender is of type Link, then all menus associated with that
link are
    iterated through and rebuilt.
    """
    def __init__(self, instance):
        from asqcom.apps.staticpages.models import Menu, Link,
CachedMenuXhtml
        self.Link = Link
        self.Menu = Menu
        self.CachedMenuXhtml = CachedMenuXhtml
        self.instance = instance
        self.menus_to_build = []
        self.xhtml_for_menus = []
        self.menus_for_cache = []
        threading.Thread.__init__(self)

    def _cache_menu(self, menu, xhtml):
        """
        Stores xhtml into the CachedMenuXhtml table where the row's
menu matches
        the menu_obj.
        """
        if menu and xhtml:
            print menu
            print xhtml
            cm = self.CachedMenuXhtml.objects.filter(menu__exact=menu)
            if cm[0]:
                cm[0].xhtml = xhtml
                cm[0].save()
            else:
                new_cm = self.CachedMenuXhtml(menu=menu,xhtml=xhtml)
                new_cm.save()

    def cache_menus(self):
        """
        Unpacks the menu objects and the XHTML for that menu and
iterates
        through the list calling _cache_menu which does the real work.
        """
        for pair in self.menus_for_cache:
            self._cache_menu(pair[0],pair[1])

    def _generate_xhtml(self, menu):
        link_tmpl = get_template(LINK_TEMPLATE or 'staticpages/
link_default.html')
        menu_tmpl = get_template(MENU_TEMPLATE or 'staticpages/
menu_default.html')

        # Retrieve all links associated with this menu
        links = menu.links.all().order_by('text')
        links_strings = []
        for link in links:
            link_ctx = Context({'title': mark_safe(link.title),
                                'url': mark_safe(link.url),
                                'text': mark_safe(link.text)})
            links_strings.append(link_tmpl.render(link_ctx))
        # Create the menu context, all that is missing from here is
are the links
        menu_ctx = Context({'title': mark_safe(menu.title),
                            'menu_css_id': mark_safe(MENU_CSS_ID),
                            'links': mark_safe(''.join
(links_strings))})
        return menu_tmpl.render(menu_ctx)

    def run(self):
        if isinstance(self.instance, self.Link):
            menus = self.Menu.objects.filter
(links__exact=self.instance)
            for menu in menus:
                self.menus_to_build.append(menu)
        else:
            self.menus_to_build.append(self.instance)
        for menu in self.menus_to_build:
            self.xhtml_for_menus.append(self._generate_xhtml(menu))
        self.menus_for_cache = zip(self.menus_to_build,
self.xhtml_for_menus)
        self.cache_menus()

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

Reply via email to