def decorate_model(model): """ Add attributes and methods to a google db Model instance to allow functions in the django admin to work as expected. """ # Grab the app_label from the models module path # myproject.myapp.models.MyModel => 'myapp' app_label = re.sub('\.models$', '', model.__module__).split('.')[-1] if not hasattr(model, 'Meta'): setattr(model, 'Meta', DefaultMeta) opts = Options(model.Meta, app_label) opts.pk = PK opts.contribute_to_class(model, 'NAME_DOES_NOT_APPEAR_TO_BE_USED') # Add some methods that Django uses model.serializable_value = lambda m, attr: getattr(m, attr) model._deferred = False model._get_pk_val = lambda m: str(m.key) model._get_id = lambda m: m.key.id() model.id = property(model._get_id) model.pk = property(model._get_pk_val) return model
def get_default_meta_options(cls): """Generate default options for Meta and return them as a dict. """ default_meta_options = Options(None).__dict__ cleaned_default_meta_options = dict() for attr, value in default_meta_options.items(): if attr in META_OPTIONS: cleaned_default_meta_options[attr] = value return cleaned_default_meta_options
def join_to_table( table, table2, table_field, table2_field, queryset, alias, extra_restriction_func=lambda where_class, alias, related_alias: None): """ Add a join on `table2` to `queryset` (having table `table`). """ foreign_object = ForeignObject(to=table2, from_fields=[None], to_fields=[None], rel=None) foreign_object.opts = Options(table._meta) foreign_object.opts.model = table foreign_object.get_joining_columns = lambda: ( (table_field, table2_field), ) foreign_object.get_extra_restriction = extra_restriction_func join = Join(table2._meta.db_table, table._meta.db_table, alias, LOUTER, foreign_object, True) queryset.query.join(join) # hook for set alias join.table_alias = alias queryset.query.external_aliases.add(alias) return queryset
def __new__(cls, name, bases, attrs): super_new = super(ModelBase, cls).__new__ module = attrs.pop('__module__') new_class = super_new(cls, name, bases, {'__module__': module}) # Get meta from parent class attr_meta = attrs.pop('Meta', None) abstract = getattr(attr_meta, 'abstract', False) app_label = getattr(attr_meta, 'app_label', None) # Get meta from created child new_meta = getattr(new_class, 'Meta', None) abstract = abstract or getattr(new_meta, 'abstract', False) app_label = app_label or getattr(new_meta, 'app_label', None) # Create _meta attribute new_class._meta = Options(new_meta, app_label=app_label) if attr_meta: for attr_name, attr in attr_meta.__dict__.items(): if attr_name.startswith('_'): continue setattr(new_class._meta, attr_name, attr) # Put class attrs for attr_name, attr in attrs.items(): setattr(new_class, attr_name, attr) return new_class
def __new__(cls, name, bases, attrs): # If this isn't a subclass of Model, don't do anything special. try: parents = [b for b in bases if issubclass(b, Model)] if not parents: return super(ModelBase, cls).__new__(cls, name, bases, attrs) except NameError: # 'Model' isn't defined yet, meaning we're looking at Django's own # Model class, defined below. return super(ModelBase, cls).__new__(cls, name, bases, attrs) # Create the class. new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')}) new_class.add_to_class('_meta', Options(attrs.pop('Meta', None))) new_class.add_to_class('DoesNotExist', types.ClassType('DoesNotExist', (ObjectDoesNotExist,), {})) new_class.add_to_class('MultipleObjectsReturned', types.ClassType('MultipleObjectsReturned', (MultipleObjectsReturned, ), {})) # Build complete list of parents for base in parents: # Things without _meta aren't functional models, so they're # uninteresting parents. if hasattr(base, '_meta'): new_class._meta.parents.append(base) new_class._meta.parents.extend(base._meta.parents) if getattr(new_class._meta, 'app_label', None) is None: # Figure out the app_label by looking one level up. # For 'django.contrib.sites.models', this would be 'sites'. model_module = sys.modules[new_class.__module__] new_class._meta.app_label = model_module.__name__.split('.')[-2] # Bail out early if we have already created this class. m = get_model(new_class._meta.app_label, name, False) if m is not None: return m # Add all attributes to the class. for obj_name, obj in attrs.items(): new_class.add_to_class(obj_name, obj) # Add Fields inherited from parents for parent in new_class._meta.parents: for field in parent._meta.fields: # Only add parent fields if they aren't defined for this class. try: new_class._meta.get_field(field.name) except FieldDoesNotExist: field.contribute_to_class(new_class, field.name) new_class._prepare() register_models(new_class._meta.app_label, new_class) # Because of the way imports happen (recursively), we may or may not be # the first class for this model to register with the framework. There # should only be one class for each model, so we must always return the # registered version. return get_model(new_class._meta.app_label, name, False)
def create_model_like_form(original_form, formadmin=None): """ This is a horrific hack to make the admin accept a Form class. It takes a form instance, and optionally a form admin. It the dynamically creates a sublcass of the form, so we can monkeypatch it without changing the original. It then primarily adds a _meta property that adds a number of properties that the admin expects to be there for a model. """ from formadmin.admin import FormAdmin if not formadmin: formadmin = FormAdmin name = "ModelLikeForm%s" % original_form.__name__ form = type('AdminCompatible%s' % name, (original_form,), {}) form.__name__ = original_form.__name__ class Meta: pass meta = Options(Meta) meta.app_label = getattr(formadmin, 'app_label', settings.FORMADMIN_APP_LABEL) meta.module_name = original_form.__name__.lower() meta.verbose_name_plural = getattr(formadmin, 'verbose_name', original_form.__name__) meta.verbose_name = getattr(formadmin, 'verbose_name', original_form.__name__) meta.object_name = meta.module_name meta.managed = False form._meta = meta return form
def tube(self, request, beanstalk_daemon_pk, name='default'): """ View tube stats and list of jobs """ self._set_client(beanstalk_daemon_pk) if request.method == 'POST': # Add a new job to tube form = BeanstalkJobForm(request.POST) if form.is_valid(): self.client.use(name) self.client.put(str(form.cleaned_data.get('body', None))) else: form = BeanstalkJobForm() self.client.watch(name) # Start watching this tube jobs = [] stats_fields = ['total-jobs', 'current-watching', 'current-using', ] jobs_list = [ jl for jl in self.client.peek_ready(), self.client.peek_buried(), self.client.peek_delayed() if jl ] for job in jobs_list: job_stats = job.stats() jobs.append({ 'id': job.jid, 'age': datetime.now() - timedelta(seconds=job_stats['age']), 'state': job_stats['state'], 'body': job.body, }) opts = Options('', '') opts.verbose_name_plural = self.opts.verbose_name opts.app_name = 'django_beanstalk' return render_to_response('admin/django_beanstalk/beanstalkdaemon/tube.html', { 'form': form, 'app_label': 'django_beanstalk', 'beanstalk_daemon_pk': beanstalk_daemon_pk, 'original': self.beanstalk_daemon_str, 'name': name, 'opts': opts, 'jobs': jobs, 'stats': filter( lambda pair: pair[0] in stats_fields, self.client.stats_tube(name).items() ), 'error': self.error, }, context_instance=RequestContext(request))
def __new__(cls, name, bases, attrs): # If this isn't a subclass of Model, don't do anything special. if name == 'Model' or not filter(lambda b: issubclass(b, Model), bases): return super(ModelBase, cls).__new__(cls, name, bases, attrs) # Create the class. new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')}) new_class.add_to_class('_meta', Options(attrs.pop('Meta', None))) new_class.add_to_class( 'DoesNotExist', types.ClassType('DoesNotExist', (ObjectDoesNotExist, ), {})) # Build complete list of parents for base in bases: # TODO: Checking for the presence of '_meta' is hackish. if '_meta' in dir(base): new_class._meta.parents.append(base) new_class._meta.parents.extend(base._meta.parents) model_module = sys.modules[new_class.__module__] if getattr(new_class._meta, 'app_label', None) is None: # Figure out the app_label by looking one level up. # For 'django.contrib.sites.models', this would be 'sites'. new_class._meta.app_label = model_module.__name__.split('.')[-2] # Bail out early if we have already created this class. m = get_model(new_class._meta.app_label, name, False) if m is not None: return m # Add all attributes to the class. for obj_name, obj in attrs.items(): new_class.add_to_class(obj_name, obj) # Add Fields inherited from parents for parent in new_class._meta.parents: for field in parent._meta.fields: # Only add parent fields if they aren't defined for this class. try: new_class._meta.get_field(field.name) except FieldDoesNotExist: field.contribute_to_class(new_class, field.name) new_class._prepare() register_models(new_class._meta.app_label, new_class) # Because of the way imports happen (recursively), we may or may not be # the first class for this model to register with the framework. There # should only be one class for each model, so we must always return the # registered version. return get_model(new_class._meta.app_label, name, False)
def decorate_ndb_model(model): """ Add attributes and methods to a google db Model instance to allow functions in the django admin to work as expected. """ # Grab the app_label from the models module path # myproject.myapp.models.MyModel => 'myapp' app_label = re.sub('\.models$', '', model.__module__).split('.')[-1] if not hasattr(model, 'Meta'): setattr(model, 'Meta', DefaultMeta) opts = Options(model.Meta, app_label) opts.pk = PK opts.contribute_to_class(model, 'NAME_DOES_NOT_APPEAR_TO_BE_USED') # Add some methods that Django uses model.serializable_value = lambda m, attr: getattr(m, attr) model._deferred = False model._get_pk_val = lambda m: m.key.urlsafe() model._get_id = lambda m: m.key.id() model.id = property(model._get_id) model.pk = property(model._get_pk_val) return model
def join_to(queryset, subquery, table_field, subquery_field, alias, join_type, nullable): """ Add a join on `subquery` to `queryset` (having table `table`). """ # here you can set complex clause for join def extra_join_cond(where_class, alias, related_alias): if (alias, related_alias) == ('[sys].[columns]', '[sys].[database_permissions]'): where = '[sys].[columns].[column_id] = ' \ '[sys].[database_permissions].[minor_id]' children = [ExtraWhere([where], ())] return where_class(children) return None table = queryset.model foreign_object = ForeignObject(to=subquery, on_delete=DO_NOTHING, from_fields=[None], to_fields=[None], rel=None) foreign_object.opts = Options(table._meta) foreign_object.opts.model = table foreign_object.get_joining_columns = lambda: ( (table_field, subquery_field), ) foreign_object.get_extra_restriction = extra_join_cond if isinstance(subquery.query, RawQuery): subquery_sql, subquery_params = subquery.query.sql, subquery.query.params else: subquery_sql, subquery_params = subquery.query.sql_with_params() join = CustomJoin(subquery_sql, subquery_params, table._meta.db_table, alias, join_type, foreign_object, nullable) # init first alias for this query queryset.query.get_initial_alias() # join subquery queryset.query.join(join) # hook for set alias join.table_alias = alias return queryset
def __new__(cls, name, bases, attrs): new_class = super(ModelBase, cls).__new__(cls, name, bases, attrs) new_class.objects.model = new_class new_class._default_manager.model = new_class meta = getattr(new_class, 'Meta') if getattr(meta, 'app_label', None) is None: # Figure out the app_label by looking one level up. # For 'django.contrib.sites.models', this would be 'sites'. model_module = sys.modules[new_class.__module__] kwargs = {"app_label": model_module.__name__.split('.')[-2]} else: kwargs = {"app_label": meta.app_label} new_class._meta = Options(meta, **kwargs) new_class._meta.object_name = new_class.__name__ new_class._meta.module_name = new_class.__name__.lower() new_class._meta.concrete_model = new_class if not hasattr(new_class.Meta, "verbose_name"): new_class._meta.verbose_name = new_class.__name__.lower() if not hasattr(new_class.Meta, "verbose_name_plural"): new_class._meta.verbose_name_plural = new_class._meta.verbose_name + "s" class Pk(Field): name = "pk" attname = "id" new_class._meta.pk = Pk() new_class._meta.id = Pk() new_class._meta.id.name = "id" #new_class._meta.fields.append(new_class._meta.pk) #new_class._meta.fields.append(new_class._meta.id) for attr, attr_value in attrs.items(): if hasattr(attr_value, 'contribute_to_class'): attr_value.name = attr setattr(new_class, attr, None) attr_value.name = attr new_class._meta.fields.append(attr_value) new_class._deferred = False register_models(new_class._meta.app_label, new_class) return new_class
def _meta(self): if hasattr(self.Meta, 'unique_together'): raise NotImplementedError( 'unique_together property not supported by neomodel') opts = Options(self.Meta, app_label=self.Meta.app_label) opts.contribute_to_class(self.__class__, self.__class__.__name__) for key, prop in self.__all_properties__: opts.add_field(DjangoField(prop, key), getattr(prop, 'private', False)) return opts
def join_to_queryset( table, subquery, table_field, subquery_field, queryset, alias, is_raw=False, extra_restriction_func=lambda where_class, alias, related_alias: None): """ Add a join on `subquery` to `queryset` (having table `table`). """ foreign_object = ForeignObject(to=subquery, from_fields=[None], to_fields=[None], rel=None, on_delete=models.CASCADE) foreign_object.opts = Options(table._meta) foreign_object.opts.model = table foreign_object.get_joining_columns = lambda: ( (table_field, subquery_field), ) foreign_object.get_extra_restriction = extra_restriction_func subquery_sql, subquery_params = ( subquery.query, []) if is_raw else subquery.query.sql_with_params() join = CustomJoin(subquery_sql, subquery_params, table._meta.db_table, alias, LOUTER, foreign_object, True) queryset.query.join(join) # hook for set alias join.table_alias = alias queryset.query.external_aliases.add(alias) return queryset
def join_to(table, subquery, table_field, subquery_field, queryset, alias): """ Add a join on `subquery` to `queryset` (having table `table`). """ # here you can set complex clause for join def extra_join_cond(where_class, alias, related_alias): if (alias, related_alias) == ('[sys].[columns]', '[sys].[database_permissions]'): where = '[sys].[columns].[column_id] = ' \ '[sys].[database_permissions].[minor_id]' children = [ExtraWhere([where], ())] return where_class(children) return None foreign_object = ForeignObject(to=subquery, from_fields=[None], to_fields=[None], rel=None, on_delete=models.DO_NOTHING) foreign_object.opts = Options(table._meta) foreign_object.opts.model = table foreign_object.get_joining_columns = lambda: ( (table_field, subquery_field), ) foreign_object.get_extra_restriction = extra_join_cond subquery_sql, subquery_params = subquery.query.sql_with_params() join = CustomJoin(subquery_sql, subquery_params, table._meta.db_table, alias, "LEFT JOIN", foreign_object, True) queryset.query.join(join) # hook for set alias join.table_alias = alias queryset.query.external_aliases.add(alias) return queryset
def _meta(self): opts = Options(meta=None) opts.model = MenuItem return opts
def __new__(cls, name, bases, attrs): super_new = super(ModelBase, cls).__new__ parents = [b for b in bases if isinstance(b, ModelBase)] if not parents: # If this isn't a subclass of Model, don't do anything special. return super_new(cls, name, bases, attrs) # Create the class. module = attrs.pop('__module__') new_class = super_new(cls, name, bases, {'__module__': module}) attr_meta = attrs.pop('Meta', None) abstract = getattr(attr_meta, 'abstract', False) if not attr_meta: meta = getattr(new_class, 'Meta', None) else: meta = attr_meta base_meta = getattr(new_class, '_meta', None) if getattr(meta, 'app_label', None) is None: # Figure out the app_label by looking one level up. # For 'django.contrib.sites.models', this would be 'sites'. model_module = sys.modules[new_class.__module__] kwargs = {"app_label": model_module.__name__.split('.')[-2]} else: kwargs = {} new_class.add_to_class('_meta', Options(meta, **kwargs)) if not abstract: new_class.add_to_class( 'DoesNotExist', subclass_exception( 'DoesNotExist', tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (ObjectDoesNotExist, ), module)) new_class.add_to_class( 'MultipleObjectsReturned', subclass_exception( 'MultipleObjectsReturned', tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (MultipleObjectsReturned, ), module)) if base_meta and not base_meta.abstract: # Non-abstract child classes inherit some attributes from their # non-abstract parent (unless an ABC comes before it in the # method resolution order). if not hasattr(meta, 'ordering'): new_class._meta.ordering = base_meta.ordering if not hasattr(meta, 'get_latest_by'): new_class._meta.get_latest_by = base_meta.get_latest_by is_proxy = new_class._meta.proxy if getattr(new_class, '_default_manager', None): if not is_proxy: # Multi-table inheritance doesn't inherit default manager from # parents. new_class._default_manager = None new_class._base_manager = None else: # Proxy classes do inherit parent's default manager, if none is # set explicitly. new_class._default_manager = new_class._default_manager._copy_to_model( new_class) new_class._base_manager = new_class._base_manager._copy_to_model( new_class) # Bail out early if we have already created this class. m = get_model(new_class._meta.app_label, name, seed_cache=False, only_installed=False) if m is not None: return m # Add all attributes to the class. for obj_name, obj in attrs.items(): new_class.add_to_class(obj_name, obj) # All the fields of any type declared on this model new_fields = new_class._meta.local_fields + \ new_class._meta.local_many_to_many + \ new_class._meta.virtual_fields field_names = set([f.name for f in new_fields]) # Basic setup for proxy models. if is_proxy: base = None for parent in [cls for cls in parents if hasattr(cls, '_meta')]: if parent._meta.abstract: if parent._meta.fields: raise TypeError( "Abstract base class containing model fields not permitted for proxy model '%s'." % name) else: continue if base is not None: raise TypeError( "Proxy model '%s' has more than one non-abstract model base class." % name) else: base = parent if base is None: raise TypeError( "Proxy model '%s' has no non-abstract model base class." % name) if (new_class._meta.local_fields or new_class._meta.local_many_to_many): raise FieldError("Proxy model '%s' contains model fields." % name) new_class._meta.setup_proxy(base) new_class._meta.concrete_model = base._meta.concrete_model else: new_class._meta.concrete_model = new_class # Do the appropriate setup for any model parents. o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields if isinstance(f, OneToOneField)]) for base in parents: original_base = base if not hasattr(base, '_meta'): # Things without _meta aren't functional models, so they're # uninteresting parents. continue parent_fields = base._meta.local_fields + base._meta.local_many_to_many # Check for clashes between locally declared fields and those # on the base classes (we cannot handle shadowed fields at the # moment). for field in parent_fields: if field.name in field_names: raise FieldError('Local field %r in class %r clashes ' 'with field of similar name from ' 'base class %r' % (field.name, name, base.__name__)) if not base._meta.abstract: # Concrete classes... base = base._meta.concrete_model if base in o2o_map: field = o2o_map[base] elif not is_proxy: attr_name = '%s_ptr' % base._meta.module_name field = OneToOneField(base, name=attr_name, auto_created=True, parent_link=True) new_class.add_to_class(attr_name, field) else: field = None new_class._meta.parents[base] = field else: # .. and abstract ones. for field in parent_fields: new_class.add_to_class(field.name, copy.deepcopy(field)) # Pass any non-abstract parent classes onto child. new_class._meta.parents.update(base._meta.parents) # Inherit managers from the abstract base classes. new_class.copy_managers(base._meta.abstract_managers) # Proxy models inherit the non-abstract managers from their base, # unless they have redefined any of them. if is_proxy: new_class.copy_managers(original_base._meta.concrete_managers) # Inherit virtual fields (like GenericForeignKey) from the parent # class for field in base._meta.virtual_fields: if base._meta.abstract and field.name in field_names: raise FieldError('Local field %r in class %r clashes '\ 'with field of similar name from '\ 'abstract base class %r' % \ (field.name, name, base.__name__)) new_class.add_to_class(field.name, copy.deepcopy(field)) if abstract: # Abstract base models can't be instantiated and don't appear in # the list of models for an app. We do the final setup for them a # little differently from normal models. attr_meta.abstract = False new_class.Meta = attr_meta return new_class new_class._prepare() register_models(new_class._meta.app_label, new_class) # Because of the way imports happen (recursively), we may or may not be # the first time this model tries to register with the framework. There # should only be one class for each model, so we always return the # registered version. return get_model(new_class._meta.app_label, name, seed_cache=False, only_installed=False)
def __new__(cls, name, bases, attrs): super_new = super(ModelBase, cls).__new__ # six.with_metaclass() inserts an extra class called 'NewBase' in the # inheritance tree: Model -> NewBase -> object. But the initialization # should be executed only once for a given model class. # attrs will never be empty for classes declared in the standard way # (ie. with the `class` keyword). This is quite robust. if name == 'NewBase' and attrs == {}: return super_new(cls, name, bases, attrs) # Also ensure initialization is only performed for subclasses of Model # (excluding Model class itself). parents = [b for b in bases if isinstance(b, ModelBase) and not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))] if not parents: return super_new(cls, name, bases, attrs) # Create the class. module = attrs.pop('__module__') new_class = super_new(cls, name, bases, {'__module__': module}) attr_meta = attrs.pop('Meta', None) abstract = getattr(attr_meta, 'abstract', False) if not attr_meta: meta = getattr(new_class, 'Meta', None) else: meta = attr_meta base_meta = getattr(new_class, '_meta', None) if getattr(meta, 'app_label', None) is None: # Figure out the app_label by looking one level up from the package # or module named 'models'. If no such package or module exists, # fall back to looking one level up from the module this model is # defined in. # For 'django.contrib.sites.models', this would be 'sites'. # For 'geo.models.places' this would be 'geo'. model_module = sys.modules[new_class.__module__] package_components = model_module.__name__.split('.') package_components.reverse() # find the last occurrence of 'models' try: app_label_index = package_components.index(MODELS_MODULE_NAME) + 1 except ValueError: app_label_index = 1 kwargs = {"app_label": package_components[app_label_index]} else: kwargs = {} new_class.add_to_class('_meta', Options(meta, **kwargs)) if not abstract: new_class.add_to_class('DoesNotExist', subclass_exception(str('DoesNotExist'), tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (ObjectDoesNotExist,), module, attached_to=new_class)) new_class.add_to_class('MultipleObjectsReturned', subclass_exception(str('MultipleObjectsReturned'), tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (MultipleObjectsReturned,), module, attached_to=new_class)) if base_meta and not base_meta.abstract: # Non-abstract child classes inherit some attributes from their # non-abstract parent (unless an ABC comes before it in the # method resolution order). if not hasattr(meta, 'ordering'): new_class._meta.ordering = base_meta.ordering if not hasattr(meta, 'get_latest_by'): new_class._meta.get_latest_by = base_meta.get_latest_by is_proxy = new_class._meta.proxy # If the model is a proxy, ensure that the base class # hasn't been swapped out. if is_proxy and base_meta and base_meta.swapped: raise TypeError("%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped)) if getattr(new_class, '_default_manager', None): if not is_proxy: # Multi-table inheritance doesn't inherit default manager from # parents. new_class._default_manager = None new_class._base_manager = None else: # Proxy classes do inherit parent's default manager, if none is # set explicitly. new_class._default_manager = new_class._default_manager._copy_to_model(new_class) new_class._base_manager = new_class._base_manager._copy_to_model(new_class) # Bail out early if we have already created this class. m = get_model(new_class._meta.app_label, name, seed_cache=False, only_installed=False) if m is not None: return m # Add all attributes to the class. for obj_name, obj in attrs.items(): new_class.add_to_class(obj_name, obj) # All the fields of any type declared on this model new_fields = new_class._meta.local_fields + \ new_class._meta.local_many_to_many + \ new_class._meta.virtual_fields field_names = set([f.name for f in new_fields]) # Basic setup for proxy models. if is_proxy: base = None for parent in [cls for cls in parents if hasattr(cls, '_meta')]: if parent._meta.abstract: if parent._meta.fields: raise TypeError("Abstract base class containing model fields not permitted for proxy model '%s'." % name) else: continue if base is not None: raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name) else: base = parent if base is None: raise TypeError("Proxy model '%s' has no non-abstract model base class." % name) if (new_class._meta.local_fields or new_class._meta.local_many_to_many): raise FieldError("Proxy model '%s' contains model fields." % name) new_class._meta.setup_proxy(base) new_class._meta.concrete_model = base._meta.concrete_model else: new_class._meta.concrete_model = new_class # Collect the parent links for multi-table inheritance. parent_links = {} for base in reversed([new_class] + parents): # Conceptually equivalent to `if base is Model`. if not hasattr(base, '_meta'): continue # Skip concrete parent classes. if base != new_class and not base._meta.abstract: continue # Locate OneToOneField instances. for field in base._meta.local_fields: if isinstance(field, OneToOneField): parent_links[field.rel.to] = field # Do the appropriate setup for any model parents. for base in parents: original_base = base if not hasattr(base, '_meta'): # Things without _meta aren't functional models, so they're # uninteresting parents. continue parent_fields = base._meta.local_fields + base._meta.local_many_to_many # Check for clashes between locally declared fields and those # on the base classes (we cannot handle shadowed fields at the # moment). for field in parent_fields: if field.name in field_names: raise FieldError('Local field %r in class %r clashes ' 'with field of similar name from ' 'base class %r' % (field.name, name, base.__name__)) if not base._meta.abstract: # Concrete classes... base = base._meta.concrete_model if base in parent_links: field = parent_links[base] elif not is_proxy: attr_name = '%s_ptr' % base._meta.model_name field = OneToOneField(base, name=attr_name, auto_created=True, parent_link=True) new_class.add_to_class(attr_name, field) else: field = None new_class._meta.parents[base] = field else: # .. and abstract ones. for field in parent_fields: new_class.add_to_class(field.name, copy.deepcopy(field)) # Pass any non-abstract parent classes onto child. new_class._meta.parents.update(base._meta.parents) # Inherit managers from the abstract base classes. new_class.copy_managers(base._meta.abstract_managers) # Proxy models inherit the non-abstract managers from their base, # unless they have redefined any of them. if is_proxy: new_class.copy_managers(original_base._meta.concrete_managers) # Inherit virtual fields (like GenericForeignKey) from the parent # class for field in base._meta.virtual_fields: if base._meta.abstract and field.name in field_names: raise FieldError('Local field %r in class %r clashes ' 'with field of similar name from ' 'abstract base class %r' % (field.name, name, base.__name__)) new_class.add_to_class(field.name, copy.deepcopy(field)) if abstract: # Abstract base models can't be instantiated and don't appear in # the list of models for an app. We do the final setup for them a # little differently from normal models. attr_meta.abstract = False new_class.Meta = attr_meta return new_class new_class._prepare() register_models(new_class._meta.app_label, new_class) # Because of the way imports happen (recursively), we may or may not be # the first time this model tries to register with the framework. There # should only be one class for each model, so we always return the # registered version. return get_model(new_class._meta.app_label, name, seed_cache=False, only_installed=False)
from django.db import connection from django.db.models.options import Options # This is not a great check, but it's from the same version as auto-created # tables (Django 1.2), so we use it. digest_index_names = hasattr(Options({}), 'auto_created') def generate_index_name(table, column): if digest_index_names: column = connection.creation._digest(column) return '%s_%s' % (table, column) add_field = { 'AddNonNullNonCallableColumnModel': '\n'.join([ 'ALTER TABLE `tests_testmodel` ADD COLUMN `added_field` integer ;', 'UPDATE `tests_testmodel` SET `added_field` = 1 WHERE `added_field` IS NULL;', 'ALTER TABLE `tests_testmodel` MODIFY COLUMN `added_field` integer NOT NULL;', ]), 'AddNonNullCallableColumnModel': '\n'.join([ 'ALTER TABLE `tests_testmodel` ADD COLUMN `added_field` integer ;', 'UPDATE `tests_testmodel` SET `added_field` = `int_field` WHERE `added_field` IS NULL;', 'ALTER TABLE `tests_testmodel` MODIFY COLUMN `added_field` integer NOT NULL;', ]), 'AddNullColumnWithInitialColumnModel': '\n'.join([ 'ALTER TABLE `tests_testmodel` ADD COLUMN `added_field` integer ;',
def patched_new(cls, name, bases, attrs): "Patched version of __new__" super_new = super(ModelBase, cls).__new__ # Also ensure initialization is only performed for subclasses of Model # (excluding Model class itself). parents = [b for b in bases if isinstance(b, ModelBase)] if not parents: return super_new(cls, name, bases, attrs) # Create the class. module = attrs.pop('__module__') new_class = super_new(cls, name, bases, {'__module__': module}) attr_meta = attrs.pop('Meta', None) abstract = getattr(attr_meta, 'abstract', False) if not attr_meta: meta = getattr(new_class, 'Meta', None) else: meta = attr_meta base_meta = getattr(new_class, '_meta', None) # Look for an application configuration to attach the model to. app_config = apps.get_containing_app_config(module) if getattr(meta, 'app_label', None) is None: if app_config is None: # If the model is imported before the configuration for its # application is created (#21719), or isn't in an installed # application (#21680), use the legacy logic to figure out the # app_label by looking one level up from the package or module # named 'models'. If no such package or module exists, fall # back to looking one level up from the module this model is # defined in. # For 'django.contrib.sites.models', this would be 'sites'. # For 'geo.models.places' this would be 'geo'. if abstract: kwargs = {"app_label": None} else: msg = ( "Model class %s.%s doesn't declare an explicit app_label " "and either isn't in an application in INSTALLED_APPS or " "else was imported before its application was loaded. " % (module, name)) raise RuntimeError(msg) else: kwargs = {} new_class.add_to_class('_meta', Options(meta, **kwargs)) if not abstract: new_class.add_to_class( 'DoesNotExist', subclass_exception( str('DoesNotExist'), tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (ObjectDoesNotExist,), module, attached_to=new_class)) new_class.add_to_class( 'MultipleObjectsReturned', subclass_exception( str('MultipleObjectsReturned'), tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (MultipleObjectsReturned,), module, attached_to=new_class)) if base_meta and not base_meta.abstract: # Non-abstract child classes inherit some attributes from their # non-abstract parent (unless an ABC comes before it in the # method resolution order). if not hasattr(meta, 'ordering'): new_class._meta.ordering = base_meta.ordering if not hasattr(meta, 'get_latest_by'): new_class._meta.get_latest_by = base_meta.get_latest_by is_proxy = new_class._meta.proxy # If the model is a proxy, ensure that the base class # hasn't been swapped out. if is_proxy and base_meta and base_meta.swapped: raise TypeError("%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped)) if getattr(new_class, '_default_manager', None): if not is_proxy: # Multi-table inheritance doesn't inherit default manager from # parents. new_class._default_manager = None new_class._base_manager = None else: # Proxy classes do inherit parent's default manager, if none is # set explicitly. new_class._default_manager = new_class._default_manager._copy_to_model(new_class) new_class._base_manager = new_class._base_manager._copy_to_model(new_class) # Add all attributes to the class. for obj_name, obj in attrs.items(): new_class.add_to_class(obj_name, obj) # All the fields of any type declared on this model new_fields = ( new_class._meta.local_fields + new_class._meta.local_many_to_many + new_class._meta.virtual_fields ) field_names = set(f.name for f in new_fields) # Basic setup for proxy models. if is_proxy: base = None for parent in [kls for kls in parents if hasattr(kls, '_meta')]: if parent._meta.abstract: if parent._meta.fields: raise TypeError("Abstract base class containing model fields not permitted for proxy model '%s'." % name) else: continue #if base is not None: # patch while parent._meta.proxy: # patch parent = parent._meta.proxy_for_model # patch if base is not None and base is not parent: # patch raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name) else: base = parent if base is None: raise TypeError("Proxy model '%s' has no non-abstract model base class." % name) new_class._meta.setup_proxy(base) new_class._meta.concrete_model = base._meta.concrete_model else: new_class._meta.concrete_model = new_class # Collect the parent links for multi-table inheritance. parent_links = {} for base in reversed([new_class] + parents): # Conceptually equivalent to `if base is Model`. if not hasattr(base, '_meta'): continue # Skip concrete parent classes. if base != new_class and not base._meta.abstract: continue # Locate OneToOneField instances. for field in base._meta.local_fields: if isinstance(field, OneToOneField): parent_links[field.rel.to] = field # Do the appropriate setup for any model parents. for base in parents: original_base = base if not hasattr(base, '_meta'): # Things without _meta aren't functional models, so they're # uninteresting parents. continue parent_fields = base._meta.local_fields + base._meta.local_many_to_many # Check for clashes between locally declared fields and those # on the base classes (we cannot handle shadowed fields at the # moment). for field in parent_fields: if field.name in field_names: raise FieldError( 'Local field %r in class %r clashes ' 'with field of similar name from ' 'base class %r' % (field.name, name, base.__name__) ) if not base._meta.abstract: # Concrete classes... base = base._meta.concrete_model if base in parent_links: field = parent_links[base] elif not is_proxy: attr_name = '%s_ptr' % base._meta.model_name field = OneToOneField(base, name=attr_name, auto_created=True, parent_link=True) # Only add the ptr field if it's not already present; # e.g. migrations will already have it specified if not hasattr(new_class, attr_name): new_class.add_to_class(attr_name, field) else: field = None new_class._meta.parents[base] = field else: # .. and abstract ones. for field in parent_fields: new_class.add_to_class(field.name, copy.deepcopy(field)) # Pass any non-abstract parent classes onto child. new_class._meta.parents.update(base._meta.parents) # Inherit managers from the abstract base classes. new_class.copy_managers(base._meta.abstract_managers) # Proxy models inherit the non-abstract managers from their base, # unless they have redefined any of them. if is_proxy: new_class.copy_managers(original_base._meta.concrete_managers) # Inherit virtual fields (like GenericForeignKey) from the parent # class for field in base._meta.virtual_fields: if base._meta.abstract and field.name in field_names: raise FieldError( 'Local field %r in class %r clashes ' 'with field of similar name from ' 'abstract base class %r' % (field.name, name, base.__name__) ) new_class.add_to_class(field.name, copy.deepcopy(field)) if abstract: # Abstract base models can't be instantiated and don't appear in # the list of models for an app. We do the final setup for them a # little differently from normal models. attr_meta.abstract = False new_class.Meta = attr_meta return new_class new_class._prepare() new_class._meta.apps.register_model(new_class._meta.app_label, new_class) return new_class
FILTERLVL0 = 'filterlvl0' FILTERLVL1 = 'filterlvl1' FILTERLVL2 = 'filterlvl2' actions = { LIST: _.LIST, DISABLE: _.DISABLE, ENABLE: _.ENABLE, EXPORT: _.EXPORT, IMPORT: _.IMPORT, ANTICIPATE: _.ANTICIPATE, SOURCE: _.SOURCE, FILTERLVL0: _.FILTERLVL0, FILTERLVL1: _.FILTERLVL1, FILTERLVL2: _.FILTERLVL2, } default_permissions = Options(None).default_permissions permissions = tuple(sorted(list(actions), key=lambda x: x[0])) class Base(models.Model): search_fields = [] uid = models.UUIDField(unique=True, default=uuid4, editable=False) logs = JSONField(blank=True, null=True, default=dict) is_disable = models.BooleanField(_.is_disable, default=False, editable=False) search = models.TextField(db_index=True, blank=True, null=True) date_create = models.DateTimeField(_.date_create, auto_now_add=True, editable=False) create_by = models.CharField(_.create_by,
否则 meta 就是从参数 attrs 中获得的 Meta meta = attr_meta base_meta = getattr(new_class, '_meta', None) if getattr(meta, 'app_label', None) is None: 计算得出应用名 # Figure out the app_label by looking one level up. # For 'django.contrib.sites.models', this would be 'sites'. model_module = sys.modules[new_class.__module__] kwargs = {"app_label": model_module.__name__.split('.')[-2]} else: kwargs = {} """new_class._meta 在这里添加, 值为 Options 对象""" new_class.add_to_class('_meta', Options(meta, **kwargs)) if not abstract: new_class.add_to_class('DoesNotExist', subclass_exception(str('DoesNotExist'), tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (ObjectDoesNotExist,), module, attached_to=new_class)) new_class.add_to_class('MultipleObjectsReturned', subclass_exception(str('MultipleObjectsReturned'), tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (MultipleObjectsReturned,), module, attached_to=new_class)) if base_meta and not base_meta.abstract:
def __new__(mcs, name, bases, attrs, **kwargs): super_new = super().__new__ # Also ensure initialization is only performed for subclasses of Model # (excluding Model class itself). parents = [b for b in bases if isinstance(b, ModelMeta)] if not parents: return super_new(mcs, name, bases, attrs, **kwargs) # Create the class. module = attrs.pop('__module__') new_attrs = {'__module__': module} classcell = attrs.pop('__classcell__', None) if classcell is not None: new_attrs['__classcell__'] = classcell attr_meta = attrs.pop('Meta', None) # Pass all attrs without a (Django-specific) contribute_to_class() # method to type.__new__() so that they're properly initialized # (i.e. __set_name__()). contributable_attrs = {} for obj_name, obj in list(attrs.items()): if _has_contribute_to_class(obj): contributable_attrs[obj_name] = obj else: new_attrs[obj_name] = obj new_class = super_new(mcs, name, bases, new_attrs, **kwargs) abstract = getattr(attr_meta, 'abstract', False) meta = attr_meta or getattr(new_class, 'Meta', None) base_meta = getattr(new_class, '_meta', None) app_label = None new_class.add_to_class('_meta', Options(meta, app_label)) if not abstract: new_class.add_to_class( 'DoesNotExist', subclass_exception( 'DoesNotExist', tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (ObjectDoesNotExist, ), module, attached_to=new_class)) new_class.add_to_class( 'MultipleObjectsReturned', subclass_exception( 'MultipleObjectsReturned', tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (MultipleObjectsReturned, ), module, attached_to=new_class)) if base_meta and not base_meta.abstract: # Non-abstract child classes inherit some attributes from their # non-abstract parent (unless an ABC comes before it in the # method resolution order). if not hasattr(meta, 'ordering'): new_class._meta.ordering = base_meta.ordering if not hasattr(meta, 'get_latest_by'): new_class._meta.get_latest_by = base_meta.get_latest_by is_proxy = new_class._meta.proxy # If the model is a proxy, ensure that the base class # hasn't been swapped out. if is_proxy and base_meta and base_meta.swapped: raise TypeError("%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped)) # Add remaining attributes (those with a contribute_to_class() method) # to the class. for obj_name, obj in contributable_attrs.items(): new_class.add_to_class(obj_name, obj) # All the fields of any type declared on this model new_fields = chain(new_class._meta.local_fields, new_class._meta.local_many_to_many, new_class._meta.private_fields) field_names = {f.name for f in new_fields} # Basic setup for proxy models. new_class._meta.concrete_model = new_class # Collect the parent links for multi-table inheritance. parent_links = {} for base in reversed([new_class] + parents): # Conceptually equivalent to `if base is Model`. if not hasattr(base, '_meta'): continue # Skip concrete parent classes. if base != new_class and not base._meta.abstract: continue # Locate OneToOneField instances. for field in base._meta.local_fields: if isinstance( field, OneToOneField) and field.remote_field.parent_link: related = resolve_relation(new_class, field.remote_field.model) parent_links[make_model_tuple(related)] = field # Track fields inherited from base models. inherited_attributes = set() # Do the appropriate setup for any model parents. for base in new_class.mro(): if base not in parents or not hasattr(base, '_meta'): # Things without _meta aren't functional models, so they're # uninteresting parents. inherited_attributes.update(base.__dict__) continue parent_fields = base._meta.local_fields + base._meta.local_many_to_many if not base._meta.abstract: # Check for clashes between locally declared fields and those # on the base classes. for field in parent_fields: if field.name in field_names: raise FieldError( 'Local field %r in class %r clashes with field of ' 'the same name from base class %r.' % ( field.name, name, base.__name__, )) else: inherited_attributes.add(field.name) # Concrete classes... base = base._meta.concrete_model base_key = make_model_tuple(base) if base_key in parent_links: field = parent_links[base_key] elif not is_proxy: attr_name = '%s_ptr' % base._meta.model_name field = OneToOneField( base, on_delete=CASCADE, name=attr_name, auto_created=True, parent_link=True, ) if attr_name in field_names: raise FieldError( "Auto-generated field '%s' in class %r for " "parent_link to base class %r clashes with " "declared field of the same name." % ( attr_name, name, base.__name__, )) # Only add the ptr field if it's not already present; # e.g. migrations will already have it specified if not hasattr(new_class, attr_name): new_class.add_to_class(attr_name, field) else: field = None new_class._meta.parents[base] = field else: base_parents = base._meta.parents.copy() # Add fields from abstract base class if it wasn't overridden. for field in parent_fields: if (field.name not in field_names and field.name not in new_class.__dict__ and field.name not in inherited_attributes): new_field = copy.deepcopy(field) new_class.add_to_class(field.name, new_field) # Replace parent links defined on this base by the new # field. It will be appropriately resolved if required. if field.one_to_one: for parent, parent_link in base_parents.items(): if field == parent_link: base_parents[parent] = new_field # Pass any non-abstract parent classes onto child. new_class._meta.parents.update(base_parents) # Inherit private fields (like GenericForeignKey) from the parent # class for field in base._meta.private_fields: if field.name in field_names: if not base._meta.abstract: raise FieldError( 'Local field %r in class %r clashes with field of ' 'the same name from base class %r.' % ( field.name, name, base.__name__, )) else: field = copy.deepcopy(field) if not base._meta.abstract: field.mti_inherited = True new_class.add_to_class(field.name, field) # Copy indexes so that index names are unique when models extend an # abstract model. new_class._meta.indexes = [ copy.deepcopy(idx) for idx in new_class._meta.indexes ] new_class._prepare() return new_class
def __new__(cls, name, bases, attrs): super_new = super(ModelBase, cls).__new__ parents = [b for b in bases if isinstance(b, ModelBase)] if not parents: # If this isn't a subclass of Model, don't do anything special. return super_new(cls, name, bases, attrs) # Create the class. module = attrs.pop('__module__') new_class = super_new(cls, name, bases, {'__module__': module}) attr_meta = attrs.pop('Meta', None) abstract = getattr(attr_meta, 'abstract', False) if not attr_meta: meta = getattr(new_class, 'Meta', None) else: meta = attr_meta base_meta = getattr(new_class, '_meta', None) if getattr(meta, 'app_label', None) is None: # Figure out the app_label by looking one level up. # For 'django.contrib.sites.models', this would be 'sites'. model_module = sys.modules[new_class.__module__] kwargs = {"app_label": model_module.__name__.split('.')[-2]} else: kwargs = {} new_class.add_to_class('_meta', Options(meta, **kwargs)) if not abstract: new_class.add_to_class( 'DoesNotExist', subclass_exception('DoesNotExist', ObjectDoesNotExist, module)) new_class.add_to_class( 'MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned', MultipleObjectsReturned, module)) if base_meta and not base_meta.abstract: # Non-abstract child classes inherit some attributes from their # non-abstract parent (unless an ABC comes before it in the # method resolution order). if not hasattr(meta, 'ordering'): new_class._meta.ordering = base_meta.ordering if not hasattr(meta, 'get_latest_by'): new_class._meta.get_latest_by = base_meta.get_latest_by old_default_mgr = None if getattr(new_class, '_default_manager', None): # We have a parent who set the default manager. if new_class._default_manager.model._meta.abstract: old_default_mgr = new_class._default_manager new_class._default_manager = None # Bail out early if we have already created this class. m = get_model(new_class._meta.app_label, name, False) if m is not None: return m # Add all attributes to the class. for obj_name, obj in list(attrs.items()): new_class.add_to_class(obj_name, obj) # Do the appropriate setup for any model parents. o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields if isinstance(f, OneToOneField)]) for base in parents: if not hasattr(base, '_meta'): # Things without _meta aren't functional models, so they're # uninteresting parents. continue if not base._meta.abstract: if base in o2o_map: field = o2o_map[base] field.primary_key = True new_class._meta.setup_pk(field) else: attr_name = '%s_ptr' % base._meta.module_name field = OneToOneField(base, name=attr_name, auto_created=True, parent_link=True) new_class.add_to_class(attr_name, field) new_class._meta.parents[base] = field else: # The abstract base class case. names = set([ f.name for f in new_class._meta.local_fields + new_class._meta.many_to_many ]) for field in base._meta.local_fields + base._meta.local_many_to_many: if field.name in names: raise FieldError( 'Local field %r in class %r clashes with field of similar name from abstract base class %r' % (field.name, name, base.__name__)) new_class.add_to_class(field.name, copy.deepcopy(field)) if abstract: # Abstract base models can't be instantiated and don't appear in # the list of models for an app. We do the final setup for them a # little differently from normal models. attr_meta.abstract = False new_class.Meta = attr_meta return new_class if old_default_mgr and not new_class._default_manager: new_class._default_manager = old_default_mgr._copy_to_model( new_class) new_class._prepare() register_models(new_class._meta.app_label, new_class) # Because of the way imports happen (recursively), we may or may not be # the first time this model tries to register with the framework. There # should only be one class for each model, so we always return the # registered version. return get_model(new_class._meta.app_label, name, False)
from django.db.models.options import Options autocreate_through_tables = hasattr(Options({}), 'auto_created') add_field = { 'AddNonNullNonCallableColumnModel': '\n'.join([ 'ALTER TABLE "tests_testmodel" ADD COLUMN "added_field" integer DEFAULT 1;', 'ALTER TABLE "tests_testmodel" ALTER COLUMN "added_field" DROP DEFAULT;', 'ALTER TABLE "tests_testmodel" ALTER COLUMN "added_field" SET NOT NULL;', ]), 'AddNonNullCallableColumnModel': '\n'.join([ 'ALTER TABLE "tests_testmodel" ADD COLUMN "added_field" integer ;', 'UPDATE "tests_testmodel" SET "added_field" = "int_field" WHERE "added_field" IS NULL;', 'ALTER TABLE "tests_testmodel" ALTER COLUMN "added_field" SET NOT NULL;', ]), 'AddNullColumnWithInitialColumnModel': '\n'.join([ 'ALTER TABLE "tests_testmodel" ADD COLUMN "added_field" integer DEFAULT 1;', 'ALTER TABLE "tests_testmodel" ALTER COLUMN "added_field" DROP DEFAULT;', ]), 'AddStringColumnModel': '\n'.join([ 'ALTER TABLE "tests_testmodel" ADD COLUMN "added_field" varchar(10) DEFAULT \'abc\\\'s xyz\';', 'ALTER TABLE "tests_testmodel" ALTER COLUMN "added_field" DROP DEFAULT;', 'ALTER TABLE "tests_testmodel" ALTER COLUMN "added_field" SET NOT NULL;', ]), 'AddDateColumnModel': '\n'.join([ 'ALTER TABLE "tests_testmodel" ADD COLUMN "added_field" timestamp with time zone DEFAULT 2007-12-13 16:42:00;',
from django.db.models.options import Options _options = Options({}) # Index names changed in Django 1.5, with the introduction of index_together. supports_index_together = hasattr(_options, 'index_together')
def get_field_names(opts: Options) -> List[str]: return [field.name for field in opts.get_fields()]