def catearticle_factory(class_s, category_name, model=Article): def _get_meta(category_name): class Meta: proxy = True app_label = StringWithTitle('catearticles', _('Category Articles')) verbose_name = category_name verbose_name_plural = category_name return Meta class_attrs = { 'Meta': _get_meta(category_name), '__module__': __name__, 'objects': BaseManager({ 'category__id__in': get_category(category_name).get_children(only_id=True) }) } class_name = '%s%s' % (model.__name__, class_s) model_class = ModelBase(class_name, (model, ), class_attrs) create_permission(model_class) return model_class
def banner_factory(area, cate_name=None, recommend_type=None, model=CategoryFoucsImage): def _get_meta(area, cate_name=None, recommend_type=None): banner_verbose_name = '%s - %s' % (BANNER_IMAGE_AREAS.get_label(area) + '', \ cate_name if area == BANNER_IMAGE_AREAS.TOP else RECOMMEND_TYPES.get_label(recommend_type)) class Meta: proxy = True app_label = string_with_title("banner", _("Banner Recommend")) verbose_name = banner_verbose_name verbose_name_plural = banner_verbose_name return Meta manager_cond = {'area__exact': area} class_name = '%s%s' % (model.__name__, BANNER_IMAGE_AREAS.get_key(area)) if area == BANNER_IMAGE_AREAS.TOP: cate_id = get_category(cate_name, only_id=True) manager_cond.update({'category__id': cate_id}) class_name += str(cate_id) else: manager_cond.update({'recommend_type__exact': recommend_type}) class_name += RECOMMEND_TYPES.get_key(recommend_type) class_attrs = { 'Meta': _get_meta(area, cate_name, recommend_type), '__module__': __name__, 'objects': CustomManager(manager_cond) } model_class = ModelBase(class_name, (model, ), class_attrs) create_permission(model_class) return model_class
def build_model(cls, ensure_slug_unicity_bool, handle_redirection_bool): model_name = f'{cls.__name__}_{cls.mixin.__name__}_{ensure_slug_unicity_bool}_{handle_redirection_bool}' attributes = { '__module__': 'stack_it', 'field': models.CharField("Test Field", max_length=50), 'parent': models.ForeignKey('self', related_name='children', on_delete=models.CASCADE, null=True), 'get_children': lambda x: x.children.all(), 'SLUGIFY_FROM': 'field', 'TREE_PARENT_FIELD': 'parent', 'ENSURE_SLUG_UNICITY_BOOL': ensure_slug_unicity_bool, 'HANDLE_REDIRECTION_BOOL': handle_redirection_bool } model = ModelBase(model_name, (cls.mixin, ), attributes) translator.register(model, InternationalSlugMixinTranslation) with connection.schema_editor() as schema_editor: schema_editor.create_model(model) return model
def setUp(self): # Create a dummy model which extends the mixin. A RuntimeWarning will # occur if the model is registered twice if not hasattr(self, "model"): self.model = ModelBase( "__TestModel__" + self.mixin.__name__, (self.mixin, ), {"__module__": self.mixin.__module__}, ) # Create the schema for our test model. If the table already exists, # will pass try: with connection.schema_editor() as schema_editor: schema_editor.create_model(self.model) except ProgrammingError: pass yield # Delete the schema for the test model. If no table, will pass try: with connection.schema_editor() as schema_editor: schema_editor.delete_model(self.model) except ProgrammingError: pass
def setUp(self): from django.db import connection from django.db.models.base import ModelBase from django.core.management.color import no_style from django_sphinxsearch.managers import SearchManager # Create a dummy model which extends the mixin import pudb pudb.set_trace() self.model = ModelBase('__TestModel__{}'.format(self.mixin.__name__), (self.mixin, ), {'__module__': self.mixin.__module__}) # Create the schema for our test model self._style = no_style() sql, _ = connection.creation.sql_create_model(self.model, self._style) self._cursor = connection.cursor() for statement in sql: self._cursor.execute(statement) self.model.search = SearchManager(index="test_index", fields={'data': 100}, limit=10) self.model.search.contribute_to_class(model=self.model, name="search") source_data = ( "Python is a programming language that lets you work more quickly and integrate your systems more effectively.", "You can learn to use Python and see almost immediate gains in productivity and lower maintenance costs.", "Python runs on Windows, Linux/Unix, Mac OS X, and has been ported to the Java and .NET virtual machines.", "Python is free to use, even for commercial products, because of its OSI-approved open source license.", "New to Python or choosing between Python 2 and Python 3? Read Python 2 or Python 3.", "The Python Software Foundation holds the intellectual property rights behind Python, underwrites the PyCon conference, and funds other projects in the Python community." ) for pk, data in enumerate(source_data, start=1): instance = self.model(pk=pk, data=data) instance.save()
def applistitem_factory(class_s, app_list, model=AppListItem): def _get_meta(app_list): if app_list.list_type == APP_LIST_TYPES.BANNER: class Meta: proxy = True app_label = string_with_title("banner", _("Banner Recommend")) verbose_name = app_list.name verbose_name_plural = app_list.name else: class Meta: proxy = True app_label = string_with_title("applist", _("AppList")) verbose_name = app_list.name verbose_name_plural = app_list.name return Meta objects = CustomManager({'app_list': app_list}) class_attrs = { 'Meta': _get_meta(app_list), '__module__': __name__, 'objects': objects } if app_list.list_type == APP_LIST_TYPES.BANNER: class_name = 'Banner%s%s' % (model.__name__, class_s) else: class_name = '%s%s' % (model.__name__, class_s) model_class = ModelBase(class_name, (model, ), class_attrs) create_permission(model_class) return model_class
def cateapp_factory(class_s, category_name, model=Application): def _get_meta(category_name): class Meta: proxy = True app_label = string_with_title("cateapps", _("Category Apps")) verbose_name = category_name verbose_name_plural = category_name return Meta class_attrs = { 'Meta': _get_meta(category_name), '__module__': __name__, 'objects': CustomManager({ 'category__id': get_category(category_name, only_id=True), 'review_status__gte': REVIEW_STATUS.APPROVED }) } class_name = '%s%s' % (model.__name__, class_s) model_class = ModelBase(class_name, (model, ), class_attrs) create_permission(model_class) return model_class
def setUpClass(cls): cls.model = ModelBase('__TestModel__' + cls.model.__name__, (cls.model, ), {'__module__': cls.model.__module__}) with connection.schema_editor() as schema_editor: schema_editor.create_model(cls.model) super(ModelMixinTestCase, cls).setUpClass()
def create_translations_model(model, related_name, meta, **fields): """ Create the translations model for the shared model 'model'. 'related_name' is the related name for the reverse FK from the translations model. 'meta' is a (optional) dictionary of attributes for the translations model's inner Meta class. 'fields' is a dictionary of fields to put on the translations model. Two fields are enforced on the translations model: language_code: A 15 char, db indexed field. master: A ForeignKey back to the shared model. Those two fields are unique together, this get's enforced in the inner Meta class of the translations table """ if not meta: meta = {} unique = [('language_code', 'master')] meta['unique_together'] = list(meta.get('unique_together', [])) + unique # Create inner Meta class Meta = type('Meta', (object, ), meta) if not hasattr(Meta, 'db_table'): Meta.db_table = model._meta.db_table + '%stranslation' % getattr( settings, 'NANI_TABLE_NAME_SEPARATOR', '_') Meta.app_label = model._meta.app_label name = '%sTranslation' % model.__name__ attrs = {} attrs.update(fields) attrs['Meta'] = Meta attrs['__module__'] = model.__module__ attrs['objects'] = TranslationsModelManager() attrs['language_code'] = models.CharField(max_length=15, db_index=True) # null=True is so we can prevent cascade deletion attrs['master'] = models.ForeignKey(model, related_name=related_name, editable=False, null=True) # Create and return the new model translations_model = ModelBase(name, (BaseTranslationModel, ), attrs) bases = ( model.DoesNotExist, translations_model.DoesNotExist, ) DNE = type('DoesNotExist', bases, {}) translations_model.DoesNotExist = DNE opts = translations_model._meta opts.shared_model = model # Register it as a global in the shared model's module. # This is needed so that Translation model instances, and objects which # refer to them, can be properly pickled and unpickled. The Django session # and caching frameworks, in particular, depend on this behaviour. mod = sys.modules[model.__module__] setattr(mod, name, translations_model) return translations_model
def setUpClass(cls): # # Create a dummy model which extends the mixin cls.Model = ModelBase('__TestModel__' + cls.mixins[0].__name__, cls.mixins, {'__module__': cls.mixins[0].__module__}) # Create the schema for our test model with connection.schema_editor() as schema_editor: schema_editor.create_model(cls.Model) super().setUpClass()
def setUp(self): # Create a dummy model self.model = ModelBase('__TestModel__' + self.model.__name__, (self.model, ), {'__module__': self.model.__module__}) # Create the schema for our test model with connection.schema_editor() as schema_editor: schema_editor.create_model(self.model)
def setUp(self): # Create a dummy model which extends the mixin self.model = ModelBase('__TestModel__' + self.mixin.__name__, (self.mixin, ), {'__module__': self.mixin.__module__}) # Create the database schema for our test model with connection.schema_editor() as schema_editor: schema_editor.create_model(self.model)
def create_translations_model(self, model, related_name): """ Create the translations model for a shared model. model -- the model class to create translations for related_name -- the related name for the reverse FK from the translations model. """ model_name = '%sTranslation' % model.__name__ translation_bases, translation_base_fields = self._scan_model_bases( model) attrs = self.fields.copy() attrs.update({ 'Meta': self._build_meta_class( model, translation_base_fields.union(self.fields).union( ('language_code', ))), '__module__': model.__module__, }) if not model._meta.abstract: attrs.update({ # If this class is abstract, we must not contribute management fields 'objects': TranslationsModelManager(), 'language_code': models.CharField(max_length=15, db_index=True), # Nullable so we can prevent cascade deletion 'master': models.ForeignKey(model, related_name=related_name, editable=False, null=True, on_delete=models.CASCADE), }) # Create the new model if self.base_class: translation_bases.insert(0, self.base_class) translations_model = ModelBase(model_name, tuple(translation_bases), attrs) translations_model._meta.shared_model = model if not model._meta.abstract: # Abstract models do not have a DNE class bases = ( model.DoesNotExist, translations_model.DoesNotExist, ) translations_model.DoesNotExist = type('DoesNotExist', bases, {}) # Register it as a global in the shared model's module. # This is needed so that Translation model instances, and objects which # refer to them, can be properly pickled and unpickled. The Django session # and caching frameworks, in particular, depend on this behaviour. setattr(sys.modules[model.__module__], model_name, translations_model) return translations_model
def setUpClass(cls): # Create a dummy model cls.model = ModelBase( '__TestModel__' + cls.model.__name__, (cls.model,), {'__module__': cls.model.__module__} ) # Create the schema for our test model with connection.schema_editor() as schema_editor: schema_editor.create_model(cls.model)
def setUp(self): """Create a dummy model which extends the mixin""" self.model = ModelBase( '__TestModel__' + self.mixin.__name__, (self.mixin,), {'__module__': self.mixin.__module__} ) with connection.schema_editor() as schema_editor: schema_editor.create_model(self.model)
def get_or_create_concrete_model(model): """ Returns the concrete version of argument model. Argument model may be a concrete model, in which case, it is returned as is. Otherwise a concrete model programmatically created from argument model is returned. """ try: return apps.get_model(model._meta.label_lower) except LookupError: return ModelBase(model.__name__, (model,), {"__module__": model.__module__})
def setUpClass(cls): apps = registry.apps try: cls.model = apps.get_model('aso_models', '__testmodel__abstractshrewdmodel') except LookupError: cls.model = ModelBase( f'__TestModel__{cls.abstract_model.__name__}', (cls.abstract_model, ), {'__module__': cls.abstract_model.__module__}) super().setUpClass()
def setUpTestData(cls): if not hasattr(cls, 'model'): cls.model = ModelBase('__TestModel__' + cls.mixin.__name__, (cls.mixin, ), {'__module__': cls.mixin.__module__}) try: with connection.schema_editor() as schema_editor: schema_editor.create_model(cls.model) super(AbstractModelMixinTestCase, cls).setUpClass() except OperationalError: pass
def setUpClass(cls): if not cls.mixin: raise AttributeError('Mixin not defined in {}'.format( cls.__name__)) # Create a dummy model which extends the mixin cls.model = ModelBase('__TestModel__' + cls.mixin.__name__, (cls.mixin, ), {'__module__': cls.mixin.__module__}) # Create the schema for our test model with connection.schema_editor() as schema_editor: schema_editor.create_model(cls.model) super().setUpClass()
def setUpClass(cls): super(ModelMixinTestCase, cls).setUpClass() # Create a dummy model which extends the mixin cls.model = ModelBase('__TestModel__' + cls.mixin.__name__, (cls.mixin,), {'__module__': cls.mixin.__module__}) # Create the schema for our test model cls._style = no_style() with connection.schema_editor() as editor: editor.create_model(cls.model) cls._cursor = connection.cursor()
def _create_follow_class(cls, name, target_model): attrs = { 'followable': models.ForeignKey(target_model, editable=False, on_delete=models.CASCADE), '__module__': target_model.__module__, 'model': target_model, } from .models import Follow return ModelBase(name.title() + 'Follow', (Follow, ), attrs)
def create_translations_model(model, related_name, meta, **fields): """ Create the translations model for the shared model 'model'. 'related_name' is the related name for the reverse FK from the translations model. 'meta' is a (optional) dictionary of attributes for the translations model's inner Meta class. 'fields' is a dictionary of fields to put on the translations model. Two fields are enforced on the translations model: language_code: A 15 char, db indexed field. master: A ForeignKey back to the shared model. Those two fields are unique together, this get's enforced in the inner Meta class of the translations table """ if not meta: meta = {} unique = [('language_code', 'master')] meta['unique_together'] = list(meta.get('unique_together', [])) + unique # Create inner Meta class Meta = type('Meta', (object, ), meta) if not hasattr(Meta, 'db_table'): Meta.db_table = model._meta.db_table + '%stranslation' % getattr( settings, 'NANI_TABLE_NAME_SEPARATOR', '_') name = '%sTranslation' % model.__name__ attrs = {} attrs.update(fields) attrs['Meta'] = Meta attrs['__module__'] = model.__module__ attrs['objects'] = TranslationsModelManager() attrs['language_code'] = models.CharField(max_length=15, db_index=True) # null=True is so we can prevent cascade deletion attrs['master'] = models.ForeignKey(model, related_name=related_name, editable=False, null=True) # Create and return the new model translations_model = ModelBase(name, (BaseTranslationModel, ), attrs) bases = ( model.DoesNotExist, translations_model.DoesNotExist, ) DNE = type('DoesNotExist', bases, {}) translations_model.DoesNotExist = DNE opts = translations_model._meta opts.shared_model = model return translations_model
def setUpClass(cls): # Create a dummy model which extends the mixin if not hasattr(cls, 'model'): cls.model = ModelBase( '__TestModel__' + cls.abstract_model.__name__, (cls.abstract_model, ), {'__module__': cls.abstract_model.__module__}) # Create the schema for our test model. If the table already exists, will pass try: with connection.schema_editor() as schema_editor: schema_editor.create_model(cls.model) super().setUpClass() except ProgrammingError: pass
def setUp(self): # Create a dummy model which extends the mixin. A RuntimeWarning will # occur if the model is registered twice if not hasattr(self, 'model'): self.model = ModelBase('__TestModel__' + self.mixin.__name__, (self.mixin, ), {'__module__': self.mixin.__module__}) # Create the schema for our test model. If the table already exists, # will pass try: with connection.schema_editor() as schema_editor: schema_editor.create_model(self.model) super(AbstractModelMixinTestCase, self).setUpClass() except ProgrammingError: pass
def setUpTestData(cls): # Create a dummy model which extends the mixin. A RuntimeWarning will # occur if the model is registered twice if not hasattr(cls, 'model'): cls.model = ModelBase( 'GatekeeperAbstractModel' + cls.mixin.__name__, (cls.mixin, ), {'__module__': cls.mixin.__module__}) # Create the schema for our test model. If the table already exists, # will pass try: with connection.schema_editor() as schema_editor: schema_editor.create_model(cls.model) super(AbstractModelMixinTestCase, cls).setUpClass() except OperationalError: pass
def test_view_content_validation(): model = ViewContentMixin model = ModelBase( "__TestModel__" + model.__name__, (model, ), {"__module__": model.__module__}, ) with pytest.raises(ValidationError): hp = model(view_content={"test": []}) hp.full_clean() with pytest.raises(ValidationError): hp = model(view_content={"main": []}) hp.full_clean() with pytest.raises(ValidationError): hp = model(view_content={"main": "test"}) hp.full_clean() hp = model(view_content={"main": ["test"]}) hp.full_clean()
def generate_child_partition(parent, num): opts = parent._meta partition_name = '%s_Partition%s' % (parent.__name__, num) # HACK: Attempting to initialize a model twice results in a broken model # even though ModelBase is supposed to handle this case already. Instead, # we explicitly check to make sure the model wasn't created yet by # using get_model to prevent this case. app_label = parent._meta.app_label m = loading.get_model(app_label, partition_name, seed_cache=False) if m is not None: return m partition = ModelBase(partition_name, (parent,), { '__module__': parent.__module__, 'objects': Manager(), 'Meta': type('Meta', (object,), { 'managed': True, 'db_table': '%s_%s' % (parent._meta.db_table, num), 'unique_together': opts.unique_together, }), '_shards': ShardOptions(parent=parent, num=num), }) partition.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (parent.DoesNotExist,), parent.__module__)) partition.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned', (parent.MultipleObjectsReturned,), parent.__module__)) # Connect signals so we can re-send them signaler = resend_signal(parent) for signal in (signals.pre_save, signals.post_save, signals.pre_delete, signals.post_delete, signals.pre_init, signals.post_init, signals.m2m_changed): signal.connect(signaler, sender=partition, weak=False) # Ensure the partition is available within the module scope module = sys.modules[parent.__module__] setattr(module, partition.__name__, partition) # Register all partitions with Django loading.register_models(app_label, partition) return partition
def setUpClass(cls): ''' Programmatically create a concrete subclass of the abstract model. If this particular model has been already created (by some other test case), get that one. Otherwise, create it. ''' # apps here, is a registry which stores the configuration of # installed applications, and keeps track of models # apps = registry.Apps(installed_apps=None) apps = registry.apps try: cls.model = apps.get_model('aso_models', '__testmodel__abstractshrewdmodel') except LookupError: cls.model = ModelBase( f'__TestModel__{cls.abstract_model.__name__}', (cls.abstract_model, ), {'__module__': cls.abstract_model.__module__}) super().setUpClass()
def setUpClass(cls) -> None: assert cls.mixin is not None, 'Define a `mixin` property to be able to define concrete model' class Meta(): app_label = cls.app_label # Create a dummy model which extends the mixin. A RuntimeWarning will occur if the model is registered twice if cls.model is None: cls.model = ModelBase('__Model__' + str(randint(0, 100000000)) + '__' + cls.mixin.__name__, (cls.mixin,), { '__module__': cls.mixin.__module__, 'Meta': Meta, }) cls.enhance_model() # Create the schema for our test model. If the table already exists, will pass try: with connection.schema_editor() as schema_editor: schema_editor.create_model(cls.model) super().setUpClass() except ProgrammingError: pass
def create_translations_model(model, related_name, meta, **fields): """ Create the translations model for the shared model 'model'. 'related_name' is the related name for the reverse FK from the translations model. 'meta' is a (optional) dictionary of attributes for the translations model's inner Meta class. 'fields' is a dictionary of fields to put on the translations model. Two fields are enforced on the translations model: language_code: A 15 char, db indexed field. master: A ForeignKey back to the shared model. Those two fields are unique together, this get's enforced in the inner Meta class of the translations table """ # Build a list of translation models from base classes. Depth-first scan. abstract = model._meta.abstract translation_bases = [] translation_base_fields = set() scan_bases = list(reversed( model.__bases__)) # backwards so we can use pop/extend while scan_bases: base = scan_bases.pop() if not issubclass(base, TranslatableModel) or base is TranslatableModel: continue if not base._meta.abstract: raise TypeError( 'Multi-table inheritance of translatable models is not supported. ' 'Concrete model %s is not a valid base model for %s.' % (base._meta.model_name if django.VERSION >= (1, 6) else base._meta.module_name, model._meta.model_name if django.VERSION >= (1, 6) else model._meta.module_name)) try: # The base may have translations model, then just inherit that translation_bases.append(base._meta.translations_model) translation_base_fields.update( field.name for field in base._meta.translations_model._meta.fields) except AttributeError: # But it may not, and simply inherit other abstract bases, scan them scan_bases.extend(reversed(base.__bases__)) translation_bases.append(BaseTranslationModel) # Create translation model Meta meta = meta or {} meta['abstract'] = abstract meta['db_tablespace'] = model._meta.db_tablespace meta['managed'] = model._meta.managed if model._meta.order_with_respect_to in fields: raise ValueError( 'Using a translated fields in %s.Meta.order_with_respect_to is ambiguous ' 'and hvad does not support it.' % model._meta.model_name if django.VERSION >= ( 1, 6) else model._meta.module_name) sconst, tconst = _split_together( model._meta.unique_together, translation_base_fields.union(fields).union(('language_code', )), meta, 'unique_together') model._meta.unique_together = tuple(sconst) meta['unique_together'] = tuple(tconst) if django.VERSION >= (1, 5): sconst, tconst = _split_together( model._meta.index_together, translation_base_fields.union(fields).union(('language_code', )), meta, 'index_together') model._meta.index_together = tuple(sconst) meta['index_together'] = tuple(tconst) if not abstract: unique = [('language_code', 'master')] meta['unique_together'] = list(meta.get('unique_together', [])) + unique Meta = type('Meta', (object, ), meta) if not hasattr(Meta, 'db_table'): Meta.db_table = model._meta.db_table + '%stranslation' % TABLE_NAME_SEPARATOR Meta.app_label = model._meta.app_label name = '%sTranslation' % model.__name__ # Create translation model attrs = {} attrs.update(fields) attrs['Meta'] = Meta attrs['__module__'] = model.__module__ if not abstract: # If this class is abstract, we must not contribute management fields attrs['objects'] = TranslationsModelManager() attrs['language_code'] = models.CharField(max_length=15, db_index=True) # null=True is so we can prevent cascade deletion attrs['master'] = models.ForeignKey(model, related_name=related_name, editable=False, null=True) # Create and return the new model translations_model = ModelBase(name, tuple(translation_bases), attrs) if not abstract: # Abstract models do not have a DNE class bases = ( model.DoesNotExist, translations_model.DoesNotExist, ) DNE = type('DoesNotExist', bases, {}) translations_model.DoesNotExist = DNE opts = translations_model._meta opts.shared_model = model # We need to set it here so it is available when we scan subclasses model._meta.translations_model = translations_model # Register it as a global in the shared model's module. # This is needed so that Translation model instances, and objects which # refer to them, can be properly pickled and unpickled. The Django session # and caching frameworks, in particular, depend on this behaviour. mod = sys.modules[model.__module__] setattr(mod, name, translations_model) return translations_model