1
0
mirror of https://github.com/django/django.git synced 2025-06-05 03:29:12 +00:00

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 #@register.simple_tag
def filter_interface_script_maybe(bound_field): def filter_interface_script_maybe(bound_field):
f = bound_field.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) {' \ return '<script type="text/javascript">addEvent(window, "load", function(e) {' \
' SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % ( ' SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % (
f.name, f.verbose_name, f.rel.filter_interface-1, ADMIN_MEDIA_PREFIX) 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.core.exceptions import ObjectDoesNotExist
from django.db.models.exceptions import FieldDoesNotExist, BadKeywordArguments from django.db.models.exceptions import FieldDoesNotExist, BadKeywordArguments
from django.db.models.signals import Signals
# Admin stages. # Admin stages.
ADD, CHANGE, BOTH = 1, 2, 3 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.manipulators import ModelAddManipulator, ModelChangeManipulator
from django.db.models.fields import Field, DateField, FileField, ImageField, AutoField from django.db.models.fields import AutoField
from django.db.models.fields.related import RelatedField, OneToOne, ManyToOne, ManyToMany, RECURSIVE_RELATIONSHIP_CONSTANT from django.db.models.fields.related import OneToOne, ManyToOne
from django.db.models.related import RelatedObject 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.query import orderlist2sql
from django.db.models.options import Options from django.db.models.options import Options
from django.db import connection, backend 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.core.exceptions import ObjectDoesNotExist
from django.utils.functional import curry 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() get_verbose_name = lambda class_name: re.sub('([A-Z])', ' \\1', class_name).lower().strip()
class ModelBase(type): class ModelBase(type):
"Metaclass for all models" "Metaclass for all models"
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
@ -118,6 +121,9 @@ def cmp_cls(x, y):
return 1 return 1
return 0 return 0
class Model(object): class Model(object):
__metaclass__ = ModelBase __metaclass__ = ModelBase
@ -128,9 +134,7 @@ class Model(object):
setattr(cls, name, attribute) setattr(cls, name, attribute)
add_to_class = classmethod(add_to_class) add_to_class = classmethod(add_to_class)
AddManipulator = ManipulatorDescriptor('AddManipulator', ModelAddManipulator)
ChangeManipulator = ManipulatorDescriptor('ChangeManipulator', ModelChangeManipulator)
def __repr__(self): def __repr__(self):
return '<%s object>' % self.__class__.__name__ return '<%s object>' % self.__class__.__name__
@ -141,6 +145,7 @@ class Model(object):
return not self.__eq__(other) return not self.__eq__(other)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
dispatcher.send( signal = Signals.pre_init, sender = self.__class__, args=args, kwargs=kwargs)
if kwargs: if kwargs:
for f in self._meta.fields: for f in self._meta.fields:
if isinstance(f.rel, ManyToOne): 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] raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
for i, arg in enumerate(args): for i, arg in enumerate(args):
setattr(self, self._meta.fields[i].attname, arg) setattr(self, self._meta.fields[i].attname, arg)
dispatcher.send( signal = Signals.post_init, sender = self.__class__, instance=self)
def _prepare(cls): def _prepare(cls):
cls.add_to_class( 'AddManipulator', ModelAddManipulator)
cls.add_to_class( 'ChangeManipulator', ModelChangeManipulator)
# Creates some methods once self._meta has been populated. # Creates some methods once self._meta has been populated.
if cls._meta.order_with_respect_to: 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_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) 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) _prepare = classmethod(_prepare)
@ -187,6 +198,7 @@ class Model(object):
# Run any pre-save hooks. # Run any pre-save hooks.
if hasattr(self, '_pre_save'): if hasattr(self, '_pre_save'):
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] non_pks = [f for f in self._meta.fields if not f.primary_key]
cursor = connection.cursor() cursor = connection.cursor()
@ -231,6 +243,8 @@ class Model(object):
connection.commit() connection.commit()
# Run any post-save hooks. # Run any post-save hooks.
dispatcher.send(signal=Signals.pre_save, sender = self.__class__, instance = self )
if hasattr(self, '_post_save'): if hasattr(self, '_post_save'):
self._post_save() self._post_save()
@ -283,6 +297,8 @@ class Model(object):
# Run any pre-delete hooks. # Run any pre-delete hooks.
if hasattr(instance, '_pre_delete'): if hasattr(instance, '_pre_delete'):
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(): for related in cls._meta.get_all_related_many_to_many_objects():
cursor.execute("DELETE FROM %s WHERE %s=%%s" % \ cursor.execute("DELETE FROM %s WHERE %s=%%s" % \
@ -311,14 +327,9 @@ class Model(object):
[pk_val]) [pk_val])
setattr(self, cls._meta.pk.attname, None) setattr(self, cls._meta.pk.attname, None)
for f in cls._meta.fields:
if isinstance(f, FileField) and getattr(self, f.attname): dispatcher.send(signal=Signals.post_delete, sender = cls, instance = instance )
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.
if hasattr(instance, '_post_delete'): if hasattr(instance, '_post_delete'):
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.conf import settings
from django.core import formfields, validators from django.core import formfields, validators
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
@ -6,6 +8,7 @@ from django.utils.text import capfirst
from django.utils.translation import gettext_lazy, ngettext from django.utils.translation import gettext_lazy, ngettext
import datetime, os import datetime, os
# Random entropy string used by "default" param. # Random entropy string used by "default" param.
NOT_PROVIDED = 'oijpwojefiojpanv' 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_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, '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)) 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): def get_manipulator_field_objs(self):
return [formfields.FileUploadField, formfields.HiddenField] 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.translation import gettext_lazy, string_concat
from django.utils.functional import curry from django.utils.functional import curry
from django.core import formfields from django.core import formfields
from django.db.models.signals import Signals
from django.dispatch import dispatcher
# Values for Relation.edit_inline. # Values for Relation.edit_inline.
TABULAR, STACKED = 1, 2 TABULAR, STACKED = 1, 2
@ -14,6 +16,12 @@ RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
class RelatedField(object): class RelatedField(object):
pending_lookups = {} pending_lookups = {}
dispatcher.connect(
lambda sender: RelatedField.do_pending_lookups(sender) ,
signal = Signals.class_prepared,
weak = False)
def add_lookup(cls, rel_cls, field): def add_lookup(cls, rel_cls, field):
name = field.rel.to name = field.rel.to
module = rel_cls.__module__ module = rel_cls.__module__
@ -28,6 +36,8 @@ class RelatedField(object):
field.do_related_class(other_cls, rel_cls) field.do_related_class(other_cls, rel_cls)
do_pending_lookups = classmethod(do_pending_lookups) do_pending_lookups = classmethod(do_pending_lookups)
def contribute_to_class(self, cls, name): def contribute_to_class(self, cls, name):
Field.contribute_to_class(self,cls,name) Field.contribute_to_class(self,cls,name)
other = self.rel.to other = self.rel.to

View File

@ -15,11 +15,14 @@ class ManipulatorDescriptor(object):
if instance != None: if instance != None:
raise "Manipulator accessed via instance" raise "Manipulator accessed via instance"
else: else:
class Man(self.get_base_manipulator(type), self.base): if not self.man:
pass class Man(self.get_base_manipulator(type), self.base):
Man.classinit(type) pass
Man.__name__ = self.name
return Man Man._prepare(type)
Man.__name__ = self.name
self.man = Man
return self.man
def get_base_manipulator(self, type): def get_base_manipulator(self, type):
if hasattr(type, 'MANIPULATOR'): if hasattr(type, 'MANIPULATOR'):
@ -30,7 +33,7 @@ class ManipulatorDescriptor(object):
class AutomaticManipulator(Manipulator): class AutomaticManipulator(Manipulator):
def classinit(cls, model): def _prepare(cls, model):
cls.model = model cls.model = model
cls.manager = model._default_manager cls.manager = model._default_manager
cls.opts = model._meta 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')) 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: 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')) 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): def __init__(self, original_object= None, follow=None):
self.follow = self.model._meta.get_follow(follow) 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 from __future__ import generators
import types, weakref import types, weakref
from dispatch import saferef, robustapply, errors from django.dispatch import saferef, robustapply, errors
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id: dispatcher.py,v 1.8 2004/11/26 06:37:33 mcfletch Exp $" __cvsid__ = "$Id: dispatcher.py,v 1.8 2004/11/26 06:37:33 mcfletch Exp $"