Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/infoscout/entityfk
Django app that allows you to easily add a generic foreign key to a django model.
https://github.com/infoscout/entityfk
Last synced: 30 days ago
JSON representation
Django app that allows you to easily add a generic foreign key to a django model.
- Host: GitHub
- URL: https://github.com/infoscout/entityfk
- Owner: infoscout
- Created: 2013-05-15T20:04:52.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2023-11-14T17:47:45.000Z (about 1 year ago)
- Last Synced: 2024-08-04T01:27:54.389Z (4 months ago)
- Language: Python
- Homepage:
- Size: 75.2 KB
- Stars: 3
- Watchers: 18
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# EntityFK Django App
[![CircleCI](https://circleci.com/gh/infoscout/entityfk.svg?style=svg)](https://circleci.com/gh/infoscout/entityfk)
[![codecov](https://codecov.io/gh/infoscout/entityfk/branch/master/graph/badge.svg)](https://codecov.io/gh/infoscout/entityfk)EntityFK (Entity Forieign Key) is a django app that allows you to easily add a generic foreign key to any (not just django, see section 'Providers') model.
The app is a lightweight & modified version of the [ContentType](https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/) framework built into django. The primary difference is entityfk stores a string label to associate the model, while the ContentType framework saves a content_type_id. This key change allows you to easily use entityfk for django projects across multi-dbs.
## Implementation
Add a entity foreign key to a django model:
# models.py
from entityfk import entityfk
from entityfk.managers import EntityFKManagerclass AuthorTag(models.Model):
tag_name = models.CharField(max_length=32)entity_object = entityfk.EntityForeignKey()
entity = models.CharField(max_length=32, null=False)
entity_id = models.PositiveIntegerField(null=False)objects = EntityFKManager()
Save a entity object:
book = Book.objects.get(pk=1)
author_tag = AuthorTag.objects.create(tag_name="first_book", entity_object=book)
See how the entity is stored:
>>> author_tag.entity
'app_label.book'
>>> author_tag.entity_id
1Query a table for an entity object. To do so, need to add `EntityFKManager` as managers object:
>>> tags = AuthorTag.objects.filter(entity_object=book)
['book']If you want to query a table for all records with an entity class, you can simply pass in the Class:
>>> tags = AuthorTag.objects.filter(entity=Book)
Other useful methods, return a label provided an model instance or class
>>> from entityfk import entityfk
>>> label = entity_label(book)
'app_label.book'With a label, return the django model class
>>> entityfk.entity_model(label)
## Primary keys
By default, for Django models, the pk is used as the entity_id. If you want to override it, you should define a `EntityFKMeta` class inside the modelclass, specifying the field to be used.class MyModel(models.Model):
mypk = models.CharField(...)
class EntityFKMeta(object):
pk = "mypk"## Providers
The providers module enables extensibility beyond Django. By default the DjangoModelProvider is the only active provider, so by default, entityfk works as if it would be for just Django models.
### Implementation
Providers have to implement 3 methods that enable extensibility. You can subclass `BaseProvider` for this matter. First and foremost, if a provider is not recognizing an object or reference, you should throw `TypeNotSupported`, thus the framework would move on and search for another provider... If based on the reference, you cannot find an object, throw `CannotUnserialize`.
#### to_model
Given a label (e.g.:`"rdl.receipt"`) it returns the model class (e.g.: `Receipt`), or throws `TypeNotSupported` if it is unknown.#### to_object
Given a reference-tuple (e.g.: `("rdl.receipt", 1)`) it returns the object referred to by the tuple.
Should throw `TypeNotSupported` if the label part of the tuple (`"rdl.receipt"`) is not known.
Should throw `CannotUnserialize` if the model class cannot be instantiated. (e.g.: looked up by the id)#### to_ref
Given a model object or a model class, it returns a reference-tuple to it (e.g.: `("rdl.receipt", 1)`).
Should throw `TypeNotSupported` if the model cannot be handled by this provider.
Should word with both objects and the class of the model.### Adding providers
from entityfk import providers
providers.providers = [MyProvider1(), MyProvider2()]## Future enhancements
* Support for reverse lookups, similar to the integration in the [ContentType](https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#reverse-generic-relations) framework