Some event use. Slight manipulator refactor.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1715 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Robert Wittams 2005-12-17 03:59:35 +00:00
parent 4e25fec9f4
commit dbd3869610
8 changed files with 82 additions and 25 deletions

View File

@ -201,7 +201,7 @@ auto_populated_field_script = register.simple_tag(auto_populated_field_script)
#@register.simple_tag
def filter_interface_script_maybe(bound_field):
f = bound_field.field
if f.rel and isinstance(f.rel, meta.ManyToMany) and f.rel.filter_interface:
if f.rel and isinstance(f.rel, models.ManyToMany) and f.rel.filter_interface:
return '<script type="text/javascript">addEvent(window, "load", function(e) {' \
' SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % (
f.name, f.verbose_name, f.rel.filter_interface-1, ADMIN_MEDIA_PREFIX)

View File

@ -16,6 +16,7 @@ from django.db.models.fields.related import *
from django.core.exceptions import ObjectDoesNotExist
from django.db.models.exceptions import FieldDoesNotExist, BadKeywordArguments
from django.db.models.signals import Signals
# Admin stages.
ADD, CHANGE, BOTH = 1, 2, 3

View File

@ -1,12 +1,14 @@
from django.db.models.manipulators import ManipulatorDescriptor, ModelAddManipulator, ModelChangeManipulator
from django.db.models.fields import Field, DateField, FileField, ImageField, AutoField
from django.db.models.fields.related import RelatedField, OneToOne, ManyToOne, ManyToMany, RECURSIVE_RELATIONSHIP_CONSTANT
from django.db.models.manipulators import ModelAddManipulator, ModelChangeManipulator
from django.db.models.fields import AutoField
from django.db.models.fields.related import OneToOne, ManyToOne
from django.db.models.related import RelatedObject
from django.db.models.manager import Manager, ManagerDescriptor
from django.db.models.manager import Manager
from django.db.models.query import orderlist2sql
from django.db.models.options import Options
from django.db import connection, backend
from django.db.models.signals import Signals
from django.dispatch import dispatcher
from django.core.exceptions import ObjectDoesNotExist
from django.utils.functional import curry
@ -25,6 +27,7 @@ get_module_name = lambda class_name: class_name.lower() + 's'
get_verbose_name = lambda class_name: re.sub('([A-Z])', ' \\1', class_name).lower().strip()
class ModelBase(type):
"Metaclass for all models"
def __new__(cls, name, bases, attrs):
@ -118,6 +121,9 @@ def cmp_cls(x, y):
return 1
return 0
class Model(object):
__metaclass__ = ModelBase
@ -128,9 +134,7 @@ class Model(object):
setattr(cls, name, attribute)
add_to_class = classmethod(add_to_class)
AddManipulator = ManipulatorDescriptor('AddManipulator', ModelAddManipulator)
ChangeManipulator = ManipulatorDescriptor('ChangeManipulator', ModelChangeManipulator)
def __repr__(self):
return '<%s object>' % self.__class__.__name__
@ -141,6 +145,7 @@ class Model(object):
return not self.__eq__(other)
def __init__(self, *args, **kwargs):
dispatcher.send( signal = Signals.pre_init, sender = self.__class__, args=args, kwargs=kwargs)
if kwargs:
for f in self._meta.fields:
if isinstance(f.rel, ManyToOne):
@ -171,15 +176,21 @@ class Model(object):
raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
for i, arg in enumerate(args):
setattr(self, self._meta.fields[i].attname, arg)
dispatcher.send( signal = Signals.post_init, sender = self.__class__, instance=self)
def _prepare(cls):
cls.add_to_class( 'AddManipulator', ModelAddManipulator)
cls.add_to_class( 'ChangeManipulator', ModelChangeManipulator)
# Creates some methods once self._meta has been populated.
if cls._meta.order_with_respect_to:
cls.get_next_in_order = curry(cls._get_next_or_previous_in_order, is_next=True)
cls.get_previous_in_order = curry(cls._get_next_or_previous_in_order, is_next=False)
RelatedField.do_pending_lookups(cls)
dispatcher.send( signal = Signals.class_prepared, sender = cls)
#RelatedField.do_pending_lookups(cls)
_prepare = classmethod(_prepare)
@ -187,6 +198,7 @@ class Model(object):
# Run any pre-save hooks.
if hasattr(self, '_pre_save'):
self._pre_save()
dispatcher.send( signal=Signals.pre_save, sender = self.__class__, instance = self )
non_pks = [f for f in self._meta.fields if not f.primary_key]
cursor = connection.cursor()
@ -231,6 +243,8 @@ class Model(object):
connection.commit()
# Run any post-save hooks.
dispatcher.send(signal=Signals.pre_save, sender = self.__class__, instance = self )
if hasattr(self, '_post_save'):
self._post_save()
@ -283,6 +297,8 @@ class Model(object):
# Run any pre-delete hooks.
if hasattr(instance, '_pre_delete'):
instance._pre_delete()
dispatcher.send(signal=Signals.pre_delete, sender = cls, instance = instance )
for related in cls._meta.get_all_related_many_to_many_objects():
cursor.execute("DELETE FROM %s WHERE %s=%%s" % \
@ -311,14 +327,9 @@ class Model(object):
[pk_val])
setattr(self, cls._meta.pk.attname, None)
for f in cls._meta.fields:
if isinstance(f, FileField) and getattr(self, f.attname):
file_name = getattr(instance, 'get_%s_filename' % f.name)()
# If the file exists and no other object of this type references it,
# delete it from the filesystem.
if os.path.exists(file_name) and not cls._default_manager.get_list(**{'%s__exact' % f.name: getattr(self, f.name)}):
os.remove(file_name)
# Run any post-delete hooks.
dispatcher.send(signal=Signals.post_delete, sender = cls, instance = instance )
if hasattr(instance, '_post_delete'):
instance._post_delete()

View File

@ -1,3 +1,5 @@
from django.db.models.signals import Signals
from django.dispatch import dispatcher
from django.conf import settings
from django.core import formfields, validators
from django.core.exceptions import ObjectDoesNotExist
@ -6,6 +8,7 @@ from django.utils.text import capfirst
from django.utils.translation import gettext_lazy, ngettext
import datetime, os
# Random entropy string used by "default" param.
NOT_PROVIDED = 'oijpwojefiojpanv'
@ -502,6 +505,20 @@ class FileField(Field):
setattr(cls, 'get_%s_url' % self.name, curry(cls._get_FIELD_url, field=self))
setattr(cls, 'get_%s_size' % self.name, curry(cls._get_FIELD_size, field=self))
setattr(cls, 'save_%s_file' % self.name, curry(cls._save_FIELD_file, field=self))
dispatcher.connect(
self.delete_file,
signal = Signals.post_delete,
sender = cls
)
def delete_file(self, instance):
if getattr(instance, f.attname):
file_name = getattr(instance, 'get_%s_filename' % f.name)()
# If the file exists and no other object of this type references it,
# delete it from the filesystem.
if os.path.exists(file_name) and \
not instance.__class__._default_manager.get_list(**{'%s__exact' % self.name: getattr(instance, self.attname)}):
os.remove(file_name)
def get_manipulator_field_objs(self):
return [formfields.FileUploadField, formfields.HiddenField]

View File

@ -3,7 +3,9 @@ from django.db.models.related import RelatedObject
from django.utils.translation import gettext_lazy, string_concat
from django.utils.functional import curry
from django.core import formfields
from django.db.models.signals import Signals
from django.dispatch import dispatcher
# Values for Relation.edit_inline.
TABULAR, STACKED = 1, 2
@ -14,6 +16,12 @@ RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
class RelatedField(object):
pending_lookups = {}
dispatcher.connect(
lambda sender: RelatedField.do_pending_lookups(sender) ,
signal = Signals.class_prepared,
weak = False)
def add_lookup(cls, rel_cls, field):
name = field.rel.to
module = rel_cls.__module__
@ -28,6 +36,8 @@ class RelatedField(object):
field.do_related_class(other_cls, rel_cls)
do_pending_lookups = classmethod(do_pending_lookups)
def contribute_to_class(self, cls, name):
Field.contribute_to_class(self,cls,name)
other = self.rel.to

View File

@ -15,11 +15,14 @@ class ManipulatorDescriptor(object):
if instance != None:
raise "Manipulator accessed via instance"
else:
class Man(self.get_base_manipulator(type), self.base):
pass
Man.classinit(type)
Man.__name__ = self.name
return Man
if not self.man:
class Man(self.get_base_manipulator(type), self.base):
pass
Man._prepare(type)
Man.__name__ = self.name
self.man = Man
return self.man
def get_base_manipulator(self, type):
if hasattr(type, 'MANIPULATOR'):
@ -30,7 +33,7 @@ class ManipulatorDescriptor(object):
class AutomaticManipulator(Manipulator):
def classinit(cls, model):
def _prepare(cls, model):
cls.model = model
cls.manager = model._default_manager
cls.opts = model._meta
@ -43,7 +46,11 @@ class AutomaticManipulator(Manipulator):
setattr(cls, 'isUnique%sFor%s' % (f.name, f.unique_for_month), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_month), opts, 'month'))
if f.unique_for_year:
setattr(cls, 'isUnique%sFor%s' % (f.name, f.unique_for_year), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_year), opts, 'year'))
classinit = classmethod(classinit)
_prepare = classmethod(_prepare)
def contribute_to_class(cls, other_cls, name ):
setattr(other_cls, name, ManipulatorDescriptor(name, cls))
contribute_to_class = classmethod(contribute_to_class)
def __init__(self, original_object= None, follow=None):
self.follow = self.model._meta.get_follow(follow)

View File

@ -0,0 +1,11 @@
class Signals(object):
class_prepared = object()
pre_init= object()
post_init = object()
pre_save = object()
post_save = object()
pre_delete = object()
post_delete = object()

View File

@ -27,7 +27,7 @@ Internal attributes:
"""
from __future__ import generators
import types, weakref
from dispatch import saferef, robustapply, errors
from django.dispatch import saferef, robustapply, errors
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id: dispatcher.py,v 1.8 2004/11/26 06:37:33 mcfletch Exp $"