Example #1
0
def create_reltype():
    parent_ct = get_ct(RelatedModel)
    child_ct = get_ct(AnotherRelatedModel)

    RelationshipType.objects.get_or_create(
        name="Parent Of",
        inverse_name="Child Of",
        from_type=parent_ct,
        to_type=child_ct,
    )
Example #2
0
def create_reltype():
    parent_ct = get_ct(RelatedModel)
    child_ct = get_ct(AnotherRelatedModel)

    RelationshipType.objects.get_or_create(
        name="Parent Of",
        inverse_name="Child Of",
        from_type=parent_ct,
        to_type=child_ct,
    )
Example #3
0
    def to_representation(self, obj):
        data = super(TypedAttachmentSerializer, self).to_representation(obj)

        has_parent = (
            self.parent and self.parent.parent and
            hasattr(self.parent.parent.Meta, 'model')
        )
        if has_parent:
            # This is being serialized with its parent object, don't need to
            # reference the parent again.
            pass
        else:
            # Include pointer to parent object. Collapse content_type and
            # object_id into a single attribute: the identifier for the content
            # type plus '_id' e.g. if contenttype's name is 'visit' then the
            # attribute is 'visit_id'.  This lets us pretend the generic
            # foreign key is a regular one in client.  For the value, Use
            # get_object_id insted of obj.object_id, in case the the content
            # object is an IdentifiedModel

            parent_obj = getattr(obj, self.Meta.object_field)
            if parent_obj is not None:
                idname = get_ct(parent_obj).identifier
                data[idname + '_id'] = get_object_id(parent_obj)

                # In detail views, include full parent object (without _id
                # suffix)
                if self.is_detail:
                    from wq.db import rest
                    data[idname] = rest.router.serialize(parent_obj)
        return data
Example #4
0
    def extra_routes(cls):
        routes = []
        ct = get_ct(cls.model)
        for pct in get_related_parents(ct):
            if not pct.is_registered():
                continue
            if pct.urlbase == "":
                purlbase = ""
            else:
                purlbase = pct.urlbase + "/"

            routes.append(
                Route(
                    ("^" + purlbase + r"(?P<related_" + pct.identifier + ">[^\/\?]+)/{prefix}{trailing_slash}$"),
                    mapping={"get": "list"},
                    name="{basename}-for-related-%s" % pct.identifier,
                    initkwargs={"suffix": "List"},
                )
            )

        for cct in get_related_children(ct):
            if not cct.is_registered():
                continue
            cbase = cct.urlbase
            routes.append(
                Route(
                    url="^%s-by-{prefix}" % cbase,
                    mapping={"get": "list"},
                    name="%s-by-%s" % (cct.identifier, ct.identifier),
                    initkwargs={"target": cbase, "suffix": "List"},
                )
            )

        return routes
Example #5
0
    def get_value(self, dictionary):
        # Handle attachments that are submitted together with their parent

        # Ideal case: an array of dicts; this can be handled by the default
        # implementation.  HTML JSON forms will use this approach.
        if self.field_name in dictionary:
            return super(TypedAttachmentListSerializer, self).get_value(dictionary)

        # Deprecated/"classic" form style, where each attachment is submitted
        # as form fields with names in the format [model]_[typeid] e.g.
        # annotation_23=30.5 will become {'type': 23, 'value': '30.5'}

        # Retrieve form values into more usable array/dict format
        attachments = []
        ct = get_ct(self.child.Meta.model)
        i = 0
        for atype in self.child.expected_types:
            fields = {
                afield: "%s-%s-%s" % (ct.identifier, get_object_id(atype) if atype else "", afield)
                for afield in self.child.attachment_fields
            }
            found = False
            for key in fields.values():
                if key in dictionary:
                    found = True
            if found:
                attachment = self.child.create_dict(atype, dictionary, fields, i)
                if attachment:
                    attachments.append(attachment)
                i += 1

        # Return extracted values to default implementation
        return attachments
Example #6
0
    def to_representation(self, obj):
        if hasattr(obj, 'content_type_id') and hasattr(obj, 'content_object'):
            ctype = ContentType.objects.get(pk=obj.content_type_id)
            if isinstance(obj, Identifier):
                match_str = "%s (%s)" % (obj.name, obj.slug)
            elif isinstance(obj, Annotation):
                match_str = obj.value
            else:
                match_str = str(obj)
            obj = obj.content_object
        else:
            ctype = get_ct(obj)
            match_str = str(obj)
        if not ctype.is_registered():
            raise ImproperlyConfigured(
                "Register %s to include it in search results" %
                ctype.model_class())

        obj_id = get_object_id(obj)

        url = ctype.urlbase
        if url:
            url += '/'
        url += str(obj_id)

        return {
            'id': obj_id,
            'url': url,
            'type': str(ctype),
            'label': str(obj),
            'match': match_str,
        }
Example #7
0
    def to_representation(self, obj):
        if hasattr(obj, 'content_type_id') and hasattr(obj, 'content_object'):
            ctype = ContentType.objects.get(pk=obj.content_type_id)
            if isinstance(obj, Identifier):
                match_str = "%s (%s)" % (obj.name, obj.slug)
            elif isinstance(obj, Annotation):
                match_str = obj.value
            else:
                match_str = str(obj)
            obj = obj.content_object
        else:
            ctype = get_ct(obj)
            match_str = str(obj)
        if not ctype.is_registered():
            raise ImproperlyConfigured(
                "Register %s to include it in search results"
                % ctype.model_class()
            )

        obj_id = get_object_id(obj)

        url = ctype.urlbase
        if url:
            url += '/'
        url += str(obj_id)

        return {
            'id': obj_id,
            'url': url,
            'type': str(ctype),
            'label': str(obj),
            'match': match_str,
        }
Example #8
0
    def extra_routes(cls):
        routes = []
        ct = get_ct(cls.model)
        for pct in get_related_parents(ct):
            if not pct.is_registered():
                continue
            if pct.urlbase == '':
                purlbase = ''
            else:
                purlbase = pct.urlbase + '/'

            routes.append(Route(
                (
                    '^' + purlbase + r'(?P<related_' + pct.identifier +
                    '>[^\/\?]+)/{prefix}{trailing_slash}$'
                ),
                mapping={'get': 'list'},
                name="{basename}-for-related-%s" % pct.identifier,
                initkwargs={'suffix': 'List'},
            ))

        for cct in get_related_children(ct):
            if not cct.is_registered():
                continue
            cbase = cct.urlbase
            routes.append(Route(
                url='^%s-by-{prefix}' % cbase,
                mapping={'get': 'list'},
                name="%s-by-%s" % (cct.identifier, ct.identifier),
                initkwargs={'target': cbase, 'suffix': 'List'},
            ))

        return routes
Example #9
0
    def to_representation(self, obj):
        data = super(TypedAttachmentSerializer, self).to_representation(obj)

        has_parent = (self.parent and self.parent.parent
                      and hasattr(self.parent.parent.Meta, 'model'))
        if has_parent:
            # This is being serialized with its parent object, don't need to
            # reference the parent again.
            pass
        else:
            # Include pointer to parent object. Collapse content_type and
            # object_id into a single attribute: the identifier for the content
            # type plus '_id' e.g. if contenttype's name is 'visit' then the
            # attribute is 'visit_id'.  This lets us pretend the generic
            # foreign key is a regular one in client.  For the value, Use
            # get_object_id insted of obj.object_id, in case the the content
            # object is an IdentifiedModel

            parent_obj = getattr(obj, self.object_field)
            idname = get_ct(parent_obj).identifier
            data[idname + '_id'] = get_object_id(parent_obj)

            # In detail views, include full parent object (without _id suffix)
            if self.is_detail:
                from wq.db import rest
                data[idname] = rest.router.serialize(parent_obj)
        return data
Example #10
0
 def list(self, request, *args, **kwargs):
     response = super(RelatedModelViewSet, self).list(
         request, *args, **kwargs
     )
     ct = get_ct(self.model)
     for pct in get_related_parents(ct):
         self.get_parent(pct, 'related_%s' % pct.identifier, response)
     return response
Example #11
0
def get_choices(run):
    def make_list(cls, name):
        rows = cls.objects.all()
        ct = get_ct(cls)
        result = [{
            'id': '%s/new' % ctid(ct),
            'label': "New %s" % name,
        }]
        result += [{
            'id': '%s/%s' % (ctid(ct), row.pk),
            'label': str(row),
        } for row in rows]
        return {'name': name, 'choices': result}

    meta_choices = set()

    def add_meta_choice(ct, field):
        mid = '%s:%s' % (ctid(ct), field)
        mlabel = ('%s %s' % (ct.model, field)).title()
        meta_choices.add((mid, mlabel))

    for field in Site._meta.fields:
        if field.name not in ('slug', 'name'):
            add_meta_choice(get_ct(Site), field.name)

    for field in Event._meta.fields:
        if field.name not in ('id', 'site'):
            add_meta_choice(get_ct(Event), field.name)

    for m in Identifier.objects.filter(resolved=True, field__isnull=False):
        assert (m.type == 'meta')
        add_meta_choice(m.content_type, m.field)

    meta_choices = sorted(meta_choices, key=lambda d: d[1])
    choices = [{
        'name':
        'Metadata',
        'choices': [{
            'id': key,
            'label': label
        } for key, label in sorted(meta_choices)],
    },
               make_list(Parameter, "Parameter")]
    return choices
Example #12
0
    def setUp(self):
        self.parent_ct = get_ct(RelatedModel)
        self.child_ct = get_ct(AnotherRelatedModel)
        self.reltype = RelationshipType.objects.get(
            name="Parent Of",
            inverse_name="Child Of",
            from_type=self.parent_ct,
            to_type=self.child_ct,
        )
        self.parent = RelatedModel.objects.create(name="Parent1")
        self.child = AnotherRelatedModel.objects.create(name="Child1")

        Relationship.objects.create(
            type=self.reltype,
            from_content_type=self.parent_ct,
            from_object_id=self.parent.pk,
            to_content_type=self.child_ct,
            to_object_id=self.child.pk,
        )
Example #13
0
    def setUp(self):
        self.parent_ct = get_ct(RelatedModel)
        self.child_ct = get_ct(AnotherRelatedModel)
        self.reltype = RelationshipType.objects.get(
            name="Parent Of",
            inverse_name="Child Of",
            from_type=self.parent_ct,
            to_type=self.child_ct,
        )
        self.parent = RelatedModel.objects.create(name="Parent1")
        self.child = AnotherRelatedModel.objects.create(name="Child1")

        Relationship.objects.create(
            type=self.reltype,

            from_content_type=self.parent_ct,
            from_object_id=self.parent.pk,

            to_content_type=self.child_ct,
            to_object_id=self.child.pk,
        )
Example #14
0
 def make_list(cls, name):
     rows = cls.objects.all()
     ct = get_ct(cls)
     result = [{
         'id': '%s/new' % ctid(ct),
         'label': "New %s" % name,
     }]
     result += [{
         'id': '%s/%s' % (ctid(ct), row.pk),
         'label': str(row),
     } for row in rows]
     return {'name': name, 'choices': result}
Example #15
0
    def to_native(self, loc):
        has_parent = self.parent and hasattr(self.parent.opts, 'model')
        if self.as_geometry and has_parent:
            return json.loads(loc.geometry.geojson)

        data = super(LocationSerializer, self).to_native(loc)
        if has_parent:
            pass
        else:
            # Include pointer to parent object (see annotate/serializers.py)
            idname = get_ct(loc.content_object).identifier + '_id'
            data[idname] = get_object_id(loc.content_object)
        return data
Example #16
0
    def get_object_id(self, obj):
        # Try to use the same identifier that the webservice uses for
        # this parameter/site/etc.
        if get_ct(obj).is_identified:
            idents = obj.identifiers.filter(
                authority=self.webservice.authority)
        else:
            idents = []

        if len(idents) > 0:
            return idents[0].slug
        else:
            # No authority-specific IDs found, use default ID for object
            return get_object_id(obj)
Example #17
0
    def to_representation(self, loc):
        has_parent = (self.parent and self.parent.parent
                      and hasattr(self.parent.parent.Meta, 'model'))
        if self.as_geometry and has_parent:
            return json.loads(loc.geometry.geojson)

        data = super(LocationSerializer, self).to_representation(loc)
        if has_parent:
            pass
        else:
            # Include pointer to parent object (see annotate/serializers.py)
            idname = get_ct(loc.content_object).identifier + '_id'
            data[idname] = get_object_id(loc.content_object)
        return data
Example #18
0
    def get_object_id(self, obj):
        # Try to use the same identifier that the webservice uses for
        # this parameter/site/etc.
        if get_ct(obj).is_identified:
            idents = obj.identifiers.filter(
                authority=self.webservice.authority
            )
        else:
            idents = []

        if len(idents) > 0:
            return idents[0].slug
        else:
            # No authority-specific IDs found, use default ID for object
            return get_object_id(obj)
Example #19
0
 def filter_queryset(self, request, queryset, view):
     ctype = get_ct(view.model)
     filter = {}
     for key, val in list(view.kwargs.items()) + list(request.GET.items()):
         if not key.startswith('related_'):
             continue
         if isinstance(val, list):
             val = val[0]
         for pct in get_related_parents(ctype):
             if key == 'related_' + pct.identifier:
                 pclass = pct.model_class()
                 parent = get_by_identifier(pclass.objects, val)
                 objs = view.model.objects.filter_by_related(parent)
                 filter['pk__in'] = objs.values_list('pk', flat=True)
     return queryset.filter(**filter)
Example #20
0
 def right_dict(self):
     key = self._cache_prefix + str(self.pk)
     cache = type(self)._dict_cache
     if key not in cache:
         from wq.db.rest.models import get_object_id, get_ct
         obj = self.right
         oid = get_object_id(obj)
         ct = get_ct(obj)
         cache[key] = {
             'item_id': get_object_id(obj),
             'item_label': str(obj),
             'item_url': '%s/%s' % (ct.urlbase, oid),
             'item_page': ct.identifier
         }
     return cache[key]
Example #21
0
 def right_dict(self):
     key = self._cache_prefix + str(self.pk)
     cache = type(self)._dict_cache
     if key not in cache:
         from wq.db.rest.models import get_object_id, get_ct
         obj = self.right
         oid = get_object_id(obj)
         ct = get_ct(obj)
         cache[key] = {
             'item_id': get_object_id(obj),
             'item_label': str(obj),
             'item_url': '%s/%s' % (ct.urlbase, oid),
             'item_page': ct.identifier
         }
     return cache[key]
def update_columns(instance, user, post):
    matched = get_columns(instance)
    for col in matched:
        if col['type'] != 'unknown':
            continue
        val = post.get('rel_%s' % col['rel_id'], None)
        if not val:
            continue

        vtype, vid = val.split('/')
        if vtype == 'parameters':
            cls = Parameter
        elif vtype == 'metacolumns':
            cls = MetaColumn
        else:
            continue

        if vid == 'new':
            obj = cls.objects.find(col['value'])
            obj.contenttype = CONTENT_TYPES[Parameter]
            obj.save()
            ident = obj.primary_identifier
        else:
            obj = cls.objects.get_by_identifier(vid)
            ident = obj.identifiers.create(
                name=col['value']
            )

        reltype, is_new = RelationshipType.objects.get_or_create(
            from_type=get_ct(instance),
            to_type=CONTENT_TYPES[cls],
            name='Contains Column',
            inverse_name='Column In'
        )
        rel = instance.relationships.get(pk=col['rel_id'])
        rel.type = reltype
        rel.right = obj
        rel.save()

        new_metadata.send(
            sender=update_columns,
            instance=instance,
            object=obj,
            identifier=ident,
        )

    return read_columns(instance)
Example #23
0
    def to_native(self, obj):
        if hasattr(obj, 'content_type_id') and hasattr(obj, 'content_object'):
            ctype = ContentType.objects.get(pk=obj.content_type_id)
            obj = obj.content_object
        else:
            ctype = get_ct(obj)

        url = ctype.urlbase
        if url:
            url += '/'
        url += unicode(get_object_id(obj))

        return {
            'url': url,
            'type': unicode(ctype),
            'label': unicode(obj)
        }
Example #24
0
    def to_representation(self, obj):
        if hasattr(obj, 'content_type_id') and hasattr(obj, 'content_object'):
            ctype = ContentType.objects.get(pk=obj.content_type_id)
            obj = obj.content_object
        else:
            ctype = get_ct(obj)

        obj_id = get_object_id(obj)

        url = ctype.urlbase
        if url:
            url += '/'
        url += str(obj_id)

        return {
            'id': obj_id,
            'url': url,
            'type': str(ctype),
            'label': str(obj)
        }
Example #25
0
    def to_native(self, obj):
        data = super(TypedAttachmentSerializer, self).to_native(obj)

        has_parent = self.parent and hasattr(self.parent.opts, 'model')
        if has_parent:
            # This is being serialized with its parent object, don't need to
            # reference the parent again.
            pass
        else:
            # Include pointer to parent object. Collapse content_type and
            # object_id into a single attribute: the identifier for the content
            # type plus '_id' e.g. if contenttype's name is 'visit' then the
            # attribute is 'visit_id'.  This lets us pretend the generic
            # foreign key is a regular one in client.  For the value, Use
            # get_object_id insted of obj.object_id, in case the the content
            # object is an IdentifiedModel

            parent_obj = getattr(obj, self.object_field)
            idname = get_ct(parent_obj).identifier + '_id'
            data[idname] = get_object_id(parent_obj)
        return data
Example #26
0
    def field_from_native(self, data, files, field_name, into):
        # Handle attachments that are submitted together with their parent

        # Ideal case: an array of dicts, this can be handled by the default
        # implementation
        if field_name in data:
            return super(TypedAttachmentSerializer, self).field_from_native(
                data, files, field_name, into
            )
        # Common case: form submission.  In this case each attachment should
        # be submitted as form fields with names in the format [model]_[typeid]
        # e.g. annotation_23=30.5 will become {'type': 23, 'value': '30.5'}

        # Retrieve form values into more usable array/dict format
        attachments = []

        ct = get_ct(self.opts.model)
        i = 0
        for atype in self.expected_types:
            fields = {
                afield: '%s-%s-%s' % (
                    ct.identifier,
                    get_object_id(atype) if atype else '',
                    afield
                ) for afield in self.attachment_fields
            }
            found = False
            for key in fields.values():
                if key in data:
                    found = True
            if found:
                attachment = self.create_dict(atype, data, fields, i)
                if attachment:
                    attachments.append(attachment)
                i += 1

        # Send modified object to default implementation
        return super(TypedAttachmentSerializer, self).field_from_native(
            {field_name: attachments}, files, field_name, into
        )
Example #27
0
    def list(self, request, *args, **kwargs):

        response = super().list(request, *args, **kwargs)

        content_type = get_ct(self.model)
        for parent_content_type, fields in content_type.get_foreign_keys(
        ).items():
            if len(fields) == 1:
                parent = self.get_parent(parent_content_type, fields[0],
                                         response)
                if not parent: continue  # got the grandparent, not the parent
                response.data['parent_url'] = parent_content_type.urlbase
                response.data[
                    'parent_label'] = parent_content_type.name + ' list'

                for grandparent_content_type, fields in parent_content_type.get_foreign_keys(
                ).items():
                    if len(fields) == 1:
                        grandparent_model_class = grandparent_content_type.model_class(
                        )
                        parent_model_class = parent_content_type.model_class()
                        grandparent_field_name = ''
                        for field in parent_model_class._meta.fields:
                            if type(field.rel).__name__ == 'ManyToOneRel':
                                if field.rel.to == grandparent_model_class:
                                    grandparent_field_name = field.name

                        grandparent_id = parent_model_class.objects.values(
                        ).get(id=response.data['parent_id']).get(
                            grandparent_field_name + '_id')
                        response.data[
                            'parent_url'] = grandparent_content_type.urlbase + '/' + str(
                                grandparent_id
                            ) + '/' + parent_content_type.urlbase
                        # the parent_label doesn't work
                        response.data['parent_label'] += ' for ' + str(
                            getattr(parent, grandparent_field_name))

        return response
def parse_column(instance, name, head, body, body_type):
    matches = list(Identifier.objects.filter_by_identifier(name))
    if len(matches) > 0:
        matches.sort(
            key=lambda ident: PRIORITY.get(ident.content_type.name, 0)
        )
        column = matches[0].content_object
        ctype = matches[0].content_type
    else:
        column = UnknownItem.objects.find(name)
        ctype = CONTENT_TYPES[UnknownItem]

    reltype, is_new = RelationshipType.objects.get_or_create(
        from_type=get_ct(instance),
        to_type=ctype,
        name='Contains Column',
        inverse_name='Column In'
    )
    rel = instance.relationships.create(
        type=reltype,
        to_content_type=ctype,
        to_object_id=column.pk,
    )
    Range.objects.create(
        relationship=rel,
        type='head',
        start_row=head[0],
        start_column=head[1],
        end_row=head[2],
        end_column=head[3]
    )
    Range.objects.create(
        relationship=rel,
        type=body_type,
        start_row=body[0],
        start_column=body[1],
        end_row=body[2],
        end_column=body[3]
    )
Example #29
0
    def get_value(self, dictionary):
        # Handle attachments that are submitted together with their parent

        # Ideal case: an array of dicts; this can be handled by the default
        # implementation.  HTML JSON forms will use this approach.
        if self.field_name in dictionary:
            return super(TypedAttachmentListSerializer,
                         self).get_value(dictionary)

        # Deprecated/"classic" form style, where each attachment is submitted
        # as form fields with names in the format [model]_[typeid] e.g.
        # annotation_23=30.5 will become {'type': 23, 'value': '30.5'}

        # Retrieve form values into more usable array/dict format
        attachments = []
        ct = get_ct(self.child.Meta.model)
        i = 0
        for atype in self.child.expected_types:
            fields = {
                afield: '%s-%s-%s' %
                (ct.identifier, get_object_id(atype) if atype else '', afield)
                for afield in self.child.attachment_fields
            }
            found = False
            for key in fields.values():
                if key in dictionary:
                    found = True
            if found:
                attachment = self.child.create_dict(atype, dictionary, fields,
                                                    i)
                if attachment:
                    attachments.append(attachment)
                i += 1

        # Return extracted values to default implementation
        return attachments
Example #30
0
 def list(self, request, *args, **kwargs):
     response = super(RelatedModelViewSet, self).list(request, *args, **kwargs)
     ct = get_ct(self.model)
     for pct in get_related_parents(ct):
         self.get_parent(pct, "related_%s" % pct.identifier, response)
     return response
Example #31
0
def metaname(cls):
    return ctid(get_ct(cls)) + '_meta'
def read_row_identifiers(instance, user):
    coltypes = get_meta_columns(instance)
    ids = {}
    for mtype in coltypes:
        ids[mtype] = Counter()

    for row in instance.load_io():
        for mtype, cols in coltypes.items():
            counter = ids[mtype]
            meta = OrderedDict()
            for col in cols:
                meta[col['field_name']] = row[col['colnum']]
            key = tuple(meta.items())
            counter[key] += 1

    idgroups = []
    unknown_ids = 0
    for mtype in ids:
        cls = META_CLASSES[mtype]
        idinfo = {
            'type_id': mtype,
            'type_label': mtype.capitalize(),
            'ids': []
        }
        for key, count in ids[mtype].items():
            meta = OrderedDict(key)
            try:
                obj = cls.objects.get_by_natural_key(meta['id'])
            except cls.DoesNotExist:
                obj = None

            info = {
                'value': meta['id'],
                'count': count,
                'meta': [{
                    'name': k,
                    'value': v
                } for k, v in meta.items() if k != 'id']
            }
            if obj is not None:
                info['match'] = str(obj)
                # FIXME: Confirm that metadata hasn't changed
            else:
                info['ident_id'] = unknown_ids
                unknown_ids += 1
                info['unknown'] = True
                choices = instance.get_id_choices(cls, meta)
                info['choices'] = [{
                    'id': get_object_id(obj),
                    'label': str(obj),
                } for obj in choices]
                info['choices'].insert(0, {
                    'id': 'new',
                    'label': "New %s" % idinfo['type_label'],
                })

            idinfo['ids'].append(info)
        idinfo['ids'].sort(key=lambda info: info['value'])
        idgroups.append(idinfo)

    if not unknown_ids:
        # Create relationships after all IDs are resolved.

        # FIXME: parse_columns() always creates relationships, using
        # UnknownItem to stand in for unknown column identifiers.
        # Use UnknownItem here as well?

        from_type = get_ct(instance)

        for idinfo in idgroups:
            cls = META_CLASSES[idinfo['type_id']]
            to_type = get_ct(cls)
            reltype, is_new = RelationshipType.objects.get_or_create(
                from_type=from_type,
                to_type=to_type,
                name='Contains Identifier',
                inverse_name='Identifier In'
            )
            for info in idinfo['ids']:
                obj = cls.objects.get_by_natural_key(info['value'])
                rel, isnew = instance.relationships.get_or_create(
                    type=reltype,
                    to_content_type=to_type,
                    to_object_id=obj.pk,
                    from_content_type=from_type,
                    from_object_id=instance.pk,
                )

                # FIXME: create equivalent of Range objects here?

    return {
        'unknown_count': unknown_ids,
        'types': idgroups,
    }
Parameter = swapper.load_model('vera', 'Parameter')
Result = swapper.load_model('vera', 'Result')

META_CLASSES = {
    'site': Site,
    'event': Event,
    'report': Report,
    'parameter': Parameter,
    'result': Result,
}

EVENT_KEY = [val for val, cls in Event.get_natural_key_info()]
EventKey = namedtuple('EventKey', EVENT_KEY)

CONTENT_TYPES = {
    Parameter: get_ct(Parameter),
    MetaColumn: get_ct(MetaColumn),
    UnknownItem: get_ct(UnknownItem),
}

DATE_FIELDS = {
    'DateTimeField': datetime.datetime,
    'DateField': datetime.date,
}

if hasattr(settings, 'WQ_DEFAULT_REPORT_STATUS'):
    DEFAULT_STATUS = settings.WQ_DEFAULT_REPORT_STATUS
else:
    DEFAULT_STATUS = None

PRIORITY = {