<s> from django . db . models import ObjectDoesNotExist <EOL> from django . db . models . fields . related import ForeignKey , ReverseSingleRelatedObjectDescriptor <EOL> from django . contrib . contenttypes . models import ContentType <EOL> from django . contrib . contenttypes . generic import GenericForeignKey <EOL> from django . contrib . sites . models import SITE_CACHE , Site <EOL> from ella . core . cache . utils import get_cached_object <EOL> def generate_fk_class ( name , retrieve_func , limit_to_model = None ) : <EOL> class CustomForeignKey ( ForeignKey ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> if limit_to_model : <EOL> args = ( limit_to_model , ) + args <EOL> super ( CustomForeignKey , self ) . __init__ ( * args , ** kwargs ) <EOL> def contribute_to_class ( self , cls , name ) : <EOL> super ( CustomForeignKey , self ) . contribute_to_class ( cls , name ) <EOL> setattr ( cls , self . name , CachedReverseSingleRelatedObjectDescriptor ( self ) ) <EOL> def south_field_triple ( self ) : <EOL> from south . modelsinspector import introspector <EOL> args , kwargs = introspector ( self ) <EOL> return ( '<STR_LIT>' , args , kwargs ) <EOL> class CachedReverseSingleRelatedObjectDescriptor ( ReverseSingleRelatedObjectDescriptor ) : <EOL> def __get__ ( self , instance , instance_type = None ) : <EOL> if instance is None : <EOL> raise AttributeError , "<STR_LIT>" % self . field . name <EOL> cache_name = self . field . get_cache_name ( ) <EOL> try : <EOL> return getattr ( instance , cache_name ) <EOL> except AttributeError : <EOL> val = getattr ( instance , self . field . attname ) <EOL> if val is None : <EOL> if self . field . null : <EOL> return None <EOL> raise self . field . rel . to . DoesNotExist <EOL> rel_obj = retrieve_func ( self . field . rel . to , val ) <EOL> setattr ( instance , cache_name , rel_obj ) <EOL> return rel_obj <EOL> CustomForeignKey . __name__ = name <EOL> return CustomForeignKey <EOL> CachedForeignKey = generate_fk_class ( '<STR_LIT>' , lambda m , pk : get_cached_object ( m , pk = pk ) ) <EOL> def get_site ( model , pk ) : <EOL> try : <EOL> return SITE_CACHE [ pk ] <EOL> except KeyError : <EOL> SITE_CACHE [ pk ] = get_cached_object ( model , pk = pk ) <EOL> return SITE_CACHE [ pk ] <EOL> SiteForeignKey = generate_fk_class ( '<STR_LIT>' , get_site , Site ) <EOL> ContentTypeForeignKey = generate_fk_class ( '<STR_LIT>' , lambda m , pk : m . _default_manager . get_for_id ( pk ) , ContentType ) <EOL> CategoryForeignKey = generate_fk_class ( '<STR_LIT>' , lambda m , pk : m . _default_manager . get_for_id ( pk ) , '<STR_LIT>' ) <EOL> class CachedGenericForeignKey ( GenericForeignKey ) : <EOL> def __get__ ( self , instance , instance_type = None ) : <EOL> if instance is None : <EOL> return <EOL> try : <EOL> return getattr ( instance , self . cache_attr ) <EOL> except AttributeError : <EOL> rel_obj = None <EOL> f = self . model . _meta . get_field ( self . ct_field ) <EOL> ct_id = getattr ( instance , f . get_attname ( ) , None ) <EOL> if ct_id : <EOL> ct = self . get_content_type ( id = ct_id ) <EOL> try : <EOL> rel_obj = get_cached_object ( ct , pk = getattr ( instance , self . fk_field ) ) <EOL> except ObjectDoesNotExist : <EOL> pass <EOL> setattr ( instance , self . cache_attr , rel_obj ) <EOL> return rel_obj </s>
