示例#1
0
def setup_generic_relations(model_class):
    """
    Set up GenericRelations for actionable models.
    """
    Action = apps.get_model('actstream', 'action')

    if Action is None:
        raise RegistrationError(
            'Unable get actstream.Action. Potential circular imports '
            'in initialisation. Try moving actstream app to come after the '
            'apps which have models to register in the INSTALLED_APPS setting.'
        )

    related_attr_name = 'related_query_name'
    related_attr_value = 'actions_with_%s' % label(model_class)

    relations = {}
    for field in ('actor', 'target', 'action_object'):
        attr = '%s_actions' % field
        attr_value = '%s_as_%s' % (related_attr_value, field)
        kwargs = {
            'content_type_field': '%s_content_type' % field,
            'object_id_field': '%s_object_id' % field,
            related_attr_name: attr_value
        }
        rel = GenericRelation('actstream.Action', **kwargs)
        rel.contribute_to_class(model_class, attr)
        relations[field] = rel

        # @@@ I'm not entirely sure why this works
        setattr(Action, attr_value, None)
    return relations
示例#2
0
    def post_through_setup(self, cls):
        if RelatedObject is not None:  # Django < 1.8
            self.related = RelatedObject(cls, self.model, self)

        self.use_gfk = (self.through is None or issubclass(
            self.through, CommonGenericTaggedItemBase))

        # rel.to renamed to remote_field.model in Django 1.9
        if VERSION >= (1, 9):
            if not self.remote_field.model:
                self.remote_field.model = self.through._meta.get_field(
                    "tag").remote_field.model
        else:
            if not self.rel.to:
                self.rel.to = self.through._meta.get_field("tag").rel.to

        if RelatedObject is not None:  # Django < 1.8
            self.related = RelatedObject(self.through, cls, self)

        if self.use_gfk:
            tagged_items = GenericRelation(self.through)
            tagged_items.contribute_to_class(cls, 'tagged_items')

        for rel in cls._meta.local_many_to_many:
            if rel == self or not isinstance(rel, TaggableManager):
                continue
            if rel.through == self.through:
                raise ValueError(
                    'You can\'t have two TaggableManagers with the'
                    ' same through model.')
示例#3
0
def setup_generic_relations(model_class):
    """
    Set up GenericRelations for actionable models.
    """
    Action = apps.get_model('actstream', 'action')

    if Action is None:
        raise RegistrationError(
            'Unable get actstream.Action. Potential circular imports '
            'in initialisation. Try moving actstream app to come after the '
            'apps which have models to register in the INSTALLED_APPS setting.'
        )

    related_attr_name = 'related_query_name'
    related_attr_value = 'actions_with_%s' % label(model_class)

    relations = {}
    for field in ('actor', 'target', 'action_object'):
        attr = '%s_actions' % field
        attr_value = '{}_as_{}'.format(related_attr_value, field)
        kwargs = {
            'content_type_field': '%s_content_type' % field,
            'object_id_field': '%s_object_id' % field,
            related_attr_name: attr_value
        }
        rel = GenericRelation('actstream.Action', **kwargs)
        rel.contribute_to_class(model_class, attr)
        relations[field] = rel

        # @@@ I'm not entirely sure why this works
        setattr(Action, attr_value, None)
    return relations
示例#4
0
    def post_through_setup(self, cls):
        if RelatedObject is not None:  # Django < 1.8
            self.related = RelatedObject(cls, self.model, self)

        self.use_gfk = (
            self.through is None or issubclass(self.through, CommonGenericTaggedItemBase)
        )

        # rel.to renamed to remote_field.model in Django 1.9
        if VERSION >= (1, 9):
            if not self.remote_field.model:
                self.remote_field.model = self.through._meta.get_field("tag").remote_field.model
        else:
            if not self.rel.to:
                self.rel.to = self.through._meta.get_field("tag").rel.to

        if RelatedObject is not None:  # Django < 1.8
            self.related = RelatedObject(self.through, cls, self)

        if self.use_gfk:
            tagged_items = GenericRelation(self.through)
            tagged_items.contribute_to_class(cls, 'tagged_items')

        for rel in cls._meta.local_many_to_many:
            if rel == self or not isinstance(rel, TaggableManager):
                continue
            if rel.through == self.through:
                raise ValueError('You can\'t have two TaggableManagers with the'
                                 ' same through model.')
示例#5
0
文件: models.py 项目: drychetnik/FIR
def create_link(linkable_model,
                linked_model,
                linkable_link_name=None,
                verbose_name=None,
                verbose_name_plural=None):
    class LinkedModel(object):
        def __init__(self,
                     model,
                     link_name=None,
                     verbose_name=None,
                     verbose_name_plural=None,
                     reverse_link_name=None):
            self.model = model
            self.link_name = link_name
            self.reverse_link_name = reverse_link_name
            self.verbose_name = verbose_name
            self.verbose_name_plural = verbose_name_plural

    if issubclass(linkable_model, ManyLinkableModel):
        get_link_name = get_plural
    elif issubclass(linkable_model, OneLinkableModel):
        get_link_name = get_singular

    if linkable_link_name is None:
        linkable_link_name = get_link_name(linked_model)
    if verbose_name is None:
        verbose_name = linked_model._meta.verbose_name
    if verbose_name_plural is None:
        verbose_name_plural = linked_model._meta.verbose_name_plural
    linked_link_name = get_plural(linkable_model)

    if issubclass(linkable_model, ManyLinkableModel):
        field = models.ManyToManyField(linkable_model,
                                       related_name=linkable_link_name)
        setattr(linked_model, linked_link_name, field)
        field.contribute_to_class(linked_model, linked_link_name)

    elif issubclass(linkable_model, OneLinkableModel):
        linked_link_name = get_singular(linkable_model) + "_set"
        field = GenericRelation(linkable_model,
                                related_query_name=linkable_link_name)
        setattr(linked_model, linked_link_name, field)
        field.contribute_to_class(linked_model, linked_link_name)
        setattr(
            linkable_model, linkable_link_name,
            property(fget=lambda x: linkable_model.get_related(x),
                     fset=lambda x, y: linkable_model.set_related(x, y)))

    if not hasattr(linkable_model, "_LINKS") or linkable_model._LINKS is None:
        setattr(linkable_model, "_LINKS", dict())
    linkable_model._LINKS[linkable_link_name] = LinkedModel(
        linked_model,
        link_name=linkable_link_name,
        verbose_name=verbose_name,
        verbose_name_plural=verbose_name_plural,
        reverse_link_name=linked_link_name)
    return linkable_model
 def post_through_setup(self, cls):
   self.use_gfk = (
     self.through is None
   )
   self.rel.to = self.through._meta.get_field("group").rel.to
   if RelatedObject is not None:
     self.related = RelatedObject(self.through, cls, self)
   if self.use_gfk:
     groups = GenericRelation(self.through)
     groups.contribute_to_class(cls, "groups")
示例#7
0
def contribute_to_class(model):
    """
    Adds a 'maat_ranking' attribute to each instance of model.
    The attribute is a generic relation to MaatRanking, used by the
    handler to retrieve the ordered queryset.
    """
    try:
        generic_relation = GenericRelation(MaatRanking)
    except TypeError:
        # Django < 1.7
        generic_relation = GenericRelation(MaatRanking)
    generic_relation.contribute_to_class(model, 'maat_ranking')
示例#8
0
def contribute_to_class(model):
    """
    Adds a 'maat_ranking' attribute to each instance of model.
    The attribute is a generic relation to MaatRanking, used by the
    handler to retrieve the ordered queryset.
    """
    try:
        generic_relation = GenericRelation(MaatRanking)
    except TypeError:
        # Django < 1.7
        generic_relation = GenericRelation(MaatRanking)
    generic_relation.contribute_to_class(model, 'maat_ranking')
示例#9
0
    def _attach_generic_relation(self):
        '''
        Set up the generic relation for the entity
        '''
        rel_name = self.config_cls.generic_relation_related_name or \
                   'entity'

        gr_name = self.config_cls.generic_relation_attr.lower()
        generic_relation = GenericRelation(Value,
                                           object_id_field='entity_id',
                                           content_type_field='entity_ct',
                                           related_query_name=rel_name)
        generic_relation.contribute_to_class(self.model_cls, gr_name)
示例#10
0
    def _attach_generic_relation(self):
        '''
        Set up the generic relation for the entity
        '''
        rel_name = self.config_cls.generic_relation_related_name or \
                   self.model_cls.__name__

        gr_name = self.config_cls.generic_relation_attr.lower()
        generic_relation = GenericRelation(Value,
                                           object_id_field='entity_id',
                                           content_type_field='entity_ct',
                                           related_query_name=rel_name)
        generic_relation.contribute_to_class(self.model_cls, gr_name)
示例#11
0
def _inject_generic_relation(qs_or_model):
    if isinstance(qs_or_model, models.Model):
        model = qs_or_model
    elif isinstance(qs_or_model, models.QuerySet):
        model = qs_or_model.model
    else:
        raise TypeError('Can`t inject generic relation')

    try:
        model._meta.get_field(MODEL_ATTR_FIELD_NAME)
    except FieldDoesNotExist:
        generic_relation = GenericRelation(
            Attribute, related_query_name=MODEL_ATTR_FIELD_NAME)
        generic_relation.contribute_to_class(model, MODEL_ATTR_FIELD_NAME)
示例#12
0
def register_models():
    """
    Load model strings specified in settings.HISTORY_MODELS.
    """
    from django.contrib.contenttypes.fields import GenericRelation

    for model_name in settings.HISTORY_MODELS:
        model = apps.get_model(model_name)
        if model not in history_models:
            history_models.add(model)
            relation = GenericRelation('history.History',
                                       related_query_name='{}_{}' \
                                        .format(
                                            model._meta.app_label,
                                            model._meta.model_name))
            field_name = getattr(settings, 'HISTORY_FIELD_NAME', '_history')
            relation.contribute_to_class(model, field_name)
示例#13
0
    def post_through_setup(self, cls):
        self.related = RelatedObject(cls, self.model, self)
        self.use_gfk = (self.through is None
                        or issubclass(self.through, GenericTaggedItemBase))
        self.rel.to = self.through._meta.get_field("tag").rel.to
        self.related = RelatedObject(self.through, cls, self)
        if self.use_gfk:
            tagged_items = GenericRelation(self.through)
            tagged_items.contribute_to_class(cls, 'tagged_items')

        for rel in cls._meta.local_many_to_many:
            if rel == self or not isinstance(rel, TaggableManager):
                continue
            if rel.through == self.through:
                raise ValueError(
                    'You can\'t have two TaggableManagers with the'
                    ' same through model.')
示例#14
0
    def post_through_setup(self, cls):
        self.related = RelatedObject(cls, self.model, self)
        self.use_gfk = (
            self.through is None or issubclass(self.through, GenericTaggedItemBase)
        )
        self.rel.to = self.through._meta.get_field("tag").rel.to
        self.related = RelatedObject(self.through, cls, self)
        if self.use_gfk:
            tagged_items = GenericRelation(self.through)
            tagged_items.contribute_to_class(cls, 'tagged_items')

        for rel in cls._meta.local_many_to_many:
            if rel == self or not isinstance(rel, TaggableManager):
                continue
            if rel.through == self.through:
                raise ValueError('You can\'t have two TaggableManagers with the'
                                 ' same through model.')
示例#15
0
文件: models.py 项目: er587/FIR
def create_link(linkable_model, linked_model, linkable_link_name=None, verbose_name=None, verbose_name_plural=None):

    class LinkedModel(object):
        def __init__(self, model, link_name=None, verbose_name=None, verbose_name_plural=None, reverse_link_name=None):
            self.model = model
            self.link_name = link_name
            self.reverse_link_name = reverse_link_name
            self.verbose_name = verbose_name
            self.verbose_name_plural = verbose_name_plural

    if issubclass(linkable_model, ManyLinkableModel):
        get_link_name = get_plural
    elif issubclass(linkable_model, OneLinkableModel):
        get_link_name = get_singular

    if linkable_link_name is None:
        linkable_link_name = get_link_name(linked_model)
    if verbose_name is None:
        verbose_name = linked_model._meta.verbose_name
    if verbose_name_plural is None:
        verbose_name_plural = linked_model._meta.verbose_name_plural
    linked_link_name = get_plural(linkable_model)

    if issubclass(linkable_model, ManyLinkableModel):
        field = models.ManyToManyField(linkable_model, related_name=linkable_link_name)
        setattr(linked_model, linked_link_name, field)
        field.contribute_to_class(linked_model, linked_link_name)

    elif issubclass(linkable_model, OneLinkableModel):
        linked_link_name = get_singular(linkable_model)+"_set"
        field = GenericRelation(linkable_model, related_query_name=linkable_link_name)
        setattr(linked_model, linked_link_name, field)
        field.contribute_to_class(linked_model, linked_link_name)
        setattr(linkable_model, linkable_link_name, property(
            fget=lambda x: linkable_model.get_related(x),
            fset=lambda x, y: linkable_model.set_related(x, y)))

    if not hasattr(linkable_model, "_LINKS") or linkable_model._LINKS is None:
        setattr(linkable_model, "_LINKS", dict())
    linkable_model._LINKS[linkable_link_name] = LinkedModel(
                                linked_model, link_name=linkable_link_name,
                                verbose_name=verbose_name,
                                verbose_name_plural=verbose_name_plural,
                                reverse_link_name=linked_link_name)
    return linkable_model
示例#16
0
    def post_through_setup(self, cls):
        self.use_gfk = self.through is None or issubclass(
            self.through, CommonGenericTaggedItemBase)

        if not self.remote_field.model:
            self.remote_field.model = self.through._meta.get_field(
                "tag").remote_field.model

        if self.use_gfk:
            tagged_items = GenericRelation(self.through)
            tagged_items.contribute_to_class(cls, "tagged_items")

        for rel in cls._meta.local_many_to_many:
            if rel == self or not isinstance(rel, TaggableManager):
                continue
            if rel.through == self.through:
                raise ValueError("You can't have two TaggableManagers with the"
                                 " same through model.")
示例#17
0
文件: registry.py 项目: gzqichang/wa
def setup_generic_relations(model_class):
    """
    注册过的model_class实例可以如此操作:
        instance.actor_actions.filter(...)
        instance.target_actions.filter(...)
        instance.relative_actions.filter(...)
    """
    from qevent.models import Action
    related_attr_value = 'actions_with_%s' % label(model_class)
    #
    relations = {}
    for field in ('actor', 'target', 'relative'):
        attr_value = '%s_as_%s' % (related_attr_value, field)
        rel = GenericRelation(Action, 
            content_type_field='%s_type' % field,
            object_id_field='%s_object_id' % field,
            related_query_name=attr_value,
        )
        rel.contribute_to_class(model_class, '%s_actions' % field)
        relations[field] = rel
        # setattr(Action, attr_value, None)
    return relations
示例#18
0
文件: registry.py 项目: gzqichang/wa
def setup_generic_relations(model_actor, relation_methods):
    """
    注册过的 actor_model_class 实例可以如此操作:
        actor.METHOD(target) # 建立 target 的特定 RELATION
        actor.dont_METHOD(target) # 或 no_METHOD 取消 target 的特定 RELATION
        #
        actor.actor_relations.filter(...)
        actor.METHOD_relations(...) # AS actor 的特定 RELATION filter
        actor.has_METHOD(target) # 与 target 是否存在特定 RELATION
    target_model_instance 可以有如下操作:
        target.target_relations.filter(...)
        target.METHOD_related(...) # AS target 的特定 RELATION filter
        target.was_METHOD(actor) # 与 actor 是否存在特定 RELATION
    owner_model_instance 可以有如下操作:
        owner.owner_relations.filter(...)
        owner.METHOD_related(...) # AS owner 的特定 RELATION filter
    """
    from qrelation import models
    #
    rel = GenericRelation(models.Relation,
        content_type_field='actor_type',
        object_id_field='actor_id',
        related_query_name='relations_with_%s_as_%s' % (label(model_actor), 'actor'))
    rel.contribute_to_class(model_actor, 'actor_relations')
    #
    actor_type = get_contenttype(model_actor)
    for method, kwargs in relation_methods.items():
        # 'follow': {
        #     'relation': models.REL_USER_FOLLOW,
        #     'target': 'quser.User',
        # }
        model_target = validate(kwargs.pop('target'))
        if not hasattr(model_target, 'target_relations'):
            rel = GenericRelation(models.Relation,
                content_type_field='target_type',
                object_id_field='target_id',
                related_query_name='relations_with_%s_as_%s' % (label(model_target), 'target'))
            rel.contribute_to_class(model_target, 'target_relations')
        model_owner = kwargs.pop('owner', None)
        if model_owner:
            model_owner = validate(model_owner)
            owner_type = get_contenttype(model_owner)
        if model_owner and not hasattr(model_owner, 'owner_relations'):
            rel = GenericRelation(models.Relation,
                content_type_field='owner_type',
                object_id_field='owner_id',
                related_query_name='relations_with_%s_as_%s' % (label(model_owner), 'owner'))
            rel.contribute_to_class(model_owner, 'owner_relations')
        #
        target_type = get_contenttype(model_target)
        relation, owner_field = kwargs.pop('relation'), kwargs.pop('owner_field', None)
        # 建立 relation
        setattr(model_actor, method, functools.partialmethod(
            relate, relation=relation, target_type=target_type, model_target=model_target, actor_type=actor_type, owner_field=owner_field))
        cancel_method = functools.partialmethod(
            relate, relation=relation, target_type=target_type, model_target=model_target, actor_type=actor_type, deleted=True)
        # 取消 relation
        setattr(model_actor, 'dont_%s' % method, cancel_method)
        setattr(model_actor, 'no_%s' % method, cancel_method)
        # 给 actor_model 增加类方法 METHOD_relations
        setattr(model_actor, '%s_relations' % method, functools.partialmethod(
            filter_relations, relation=relation))
        # 给 actor_model 增加类方法 has_METHOD
        setattr(model_actor, 'has_%s' % method, functools.partialmethod(
            check_relation, relation=relation, target_type=target_type, model_target=model_target))
        # 给 target_model 增加类方法 METHOD_related
        setattr(model_target, '%s_related' % method, functools.partialmethod(
            filter_related, relation=relation))
        # 给 target_model 增加类方法 was_METHOD
        setattr(model_target, 'was_%s' % method, functools.partialmethod(
            check_related, relation=relation, actor_type=actor_type, model_actor=model_actor))
        if not model_owner:
            continue
        # 给 owner_model 增加类方法 
        setattr(model_owner, '%s_related' % method, functools.partialmethod(
            filter_owner, relation=relation))
示例#19
0
    def get_objects_resource(self, table_pk):
        try:
            md = ModelDefinition.objects.get(pk=table_pk)
        except ModelDefinition.DoesNotExist:
            return http.HttpNotFound()

        Model = md.model_class()

        GeomModelField = Model._meta.get_field_by_name(
            DEFAULT_MD_GEOMETRY_FIELD_NAME)[0]

        gr = GenericRelation(AttachedFile)
        gr.contribute_to_class(Model, 'files')

        proxy = self

        class AttachedFilesInlineResource(ModelResource):
            class Meta:
                queryset = AttachedFile.objects.all()

            def get_resource_uri(self, bundle):
                kwargs = dict(table_pk=md.pk,
                              object_pk=bundle.obj.object_id,
                              file_pk=bundle.obj.pk)
                return proxy.uri_for_file_detail(**kwargs)

        class R(ModelResource):
            logger = logging.getLogger('userlayers.api.data')

            class Meta:
                queryset = Model.objects.all()
                authorization = get_table_data_auth(md)()
                serializer = GeoJsonSerializer()
                max_limit = None
                validation = FormValidation(form_class=modelform_factory(
                    md.model_class(), exclude=('id', )))

            def dispatch(self, *args, **kwargs):
                response = super(R, self).dispatch(*args, **kwargs)
                ct = response.get('Content-Type')
                if ct and ct.startswith('application/zip'):
                    response[
                        'Content-Disposition'] = 'attachment; filename=%s.zip' % md.name
                return response

            def get_model_definition(self):
                return md

            def get_resource_uri(self, bundle_or_obj=None, **kwargs):
                url = proxy.uri_for_table(table_pk)
                if bundle_or_obj:
                    kw = self.resource_uri_kwargs(bundle_or_obj)
                    url += '%s%s' % (kw['pk'], trailing_slash())
                return url

            def error_response(self, request, errors, response_class=None):
                if isinstance(self._meta.serializer, GeoJsonSerializer):
                    self._meta.serializer = Serializer()
                return super(R, self).error_response(request,
                                                     errors,
                                                     response_class=None)

            def serialize(self, request, data, format, options=None):
                options = options or {}
                options['geometry_field'] = DEFAULT_MD_GEOMETRY_FIELD_NAME
                return super(R, self).serialize(request, data, format, options)

            def full_hydrate(self, bundle):
                bundle = super(R, self).full_hydrate(bundle)
                try:
                    bundle.data['geometry'] = bundle.obj.geometry
                except GDALException:
                    raise ImmediateHttpResponse(response=self.error_response(
                        bundle.request, {'geometry': 'invalid geometry'}))
                if bundle.obj.geometry and GeomModelField.dim == 3 and not bundle.obj.geometry.hasz:
                    geom_3d = bundle.obj.geometry.ogr
                    geom_3d._set_coord_dim(3)
                    bundle.data['geometry'] = geom_3d.geos

                return bundle

            def obj_create(self, bundle, **kwargs):
                bundle = super(R, self).obj_create(bundle, **kwargs)
                self.logger.info(
                    '"%s" created table data, table "%s", object pk "%s"' %
                    (bundle.request.user, md.db_table, bundle.obj.pk))
                return bundle

            def obj_update(self, bundle, **kwargs):
                bundle = super(R, self).obj_update(bundle, **kwargs)
                self.logger.info(
                    '"%s" updated table data, table "%s", object pk "%s"' %
                    (bundle.request.user, md.db_table, bundle.obj.pk))
                return bundle

            def obj_delete(self, bundle, **kwargs):
                super(R, self).obj_delete(bundle, **kwargs)
                self.logger.info(
                    '"%s" deleted table data, table "%s", object pk "%s"' %
                    (bundle.request.user, md.db_table, bundle.obj.pk))

            def dehydrate(self, bundle):
                bundle.data['files_uri'] = proxy.uri_for_file_list(
                    table_pk, bundle.obj.pk)
                return bundle

        return R
示例#20
0
 def contribute_to_class(self, cls, name):
     relation = GenericRelation(self.model,
                                related_query_name=cls._meta.model_name)
     relation.contribute_to_class(cls, name)