Re: post_save signal bug

2009-07-16 Thread Ryan K

What I tried to build is stopped by the fact that I am incorrectly
assuming that a ManyToMany field is updated at the time Menu.save() is
called (or post_save signal handler called in this case). These two
methods of customizing what happens after you save an object DO NOT
apply to ManyToMany fields because they are not updated yet. The
transaction is not complete. I think Django should abstract
transactions and allow signals like pre_transaction_finished and
post_transaction_finished in addition to the ideas found at the page
for this "bug:" http://code.djangoproject.com/ticket/5390. (this post
if for anyone searching the topic)

On Jul 11, 1:57 am, Ryan K  wrote:
> I modified the above _cached_menu method to just create a new object
> every time (shown below). It only seems to get the links right, a
> ManyToMay field, after I save it _twice_? Hmmm...how I get the updated
> many2many table?
>
> 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(menu=menu,xhtml=xhtml)
>             cm.save()
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: post_save signal bug

2009-07-10 Thread Ryan K

I modified the above _cached_menu method to just create a new object
every time (shown below). It only seems to get the links right, a
ManyToMay field, after I save it _twice_? Hmmm...how I get the updated
many2many table?

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(menu=menu,xhtml=xhtml)
cm.save()


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



post_save signal bug

2009-07-10 Thread Ryan K

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

  Cool Sites 222
  
   http://www.google.com/";>Google Inc

http://www.microsoft.com";>Microsoft

http://www.ryankaskel.com";>Ryan
Kaskel

http://www.yahoo.com";>Yahoo Homepage


  


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


  Cool Sites
  
   http://www.microsoft.com";>Microsoft

http://www.ryankaskel.com";>Ryan
Kaskel

http://www.yahoo.com";>Yahoo Homepage


  



[11/Jul/2009 05:03:47] "POST /admin/staticpages/menu/2/ HTTP/1.1" 302
0

  Cool Sites
  
   http://www.microsoft.com";>Microsoft

http://www.ryankaskel.com";>Ryan
Kaskel

http://www.yahoo.com";>Yahoo Homepage


  




  Cool Sites 222
  
   http://www.google.com/";>Google Inc

http://www.microsoft.com";>Microsoft

http://www.ryankaskel.com";>Ryan
Kaskel

http://www.yahoo.com";>Yahoo Homepage


  


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),