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:
parent
4e25fec9f4
commit
dbd3869610
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
|
@ -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 $"
|
||||
|
|
Loading…
Reference in New Issue