django Fake ORM model that query an RestAPI instead of a database —
Project description
allow to query an RestAPI (django-rest-framework + dynamic-rest) with same same interface as the django ORM. if fact, it work like any other database engin. you add the rest_models engin in an alternate database, the router, and add a APIMeta class to your models, and let’s go.
stable branche
development status
Installation
Install using pip:
pip install django-rest-models
Alternatively, you can install download or clone this repo and call
pip install -e ..
requirements
this database wrapper work with
python 2.7, 3.4, 3.5
django 1.8 , 1.9, 1.10
on the api, this is tested against
django-rest-framework 3.4, 3.5
dynamic-rest 1.5, 1.6
exemples
settings.py:
DATABASES = {
'default': {
...
},
'api': {
'ENGINE': 'rest_models.backend',
'NAME': 'https://requestb.in/',
'USER': 'userapi',
'PASSWORD': 'passwordapi',
'AUTH': 'rest_models.backend.auth.BasicAuth',
},
}
DATABASE_ROUTERS = [
'rest_models.router.RestModelRouter',
]
models.py:
class MyModel(models.Model):
field = models.IntegerField()
...
class Meta:
# basic django meta Stuff
verbose_name = 'my model'
# the only customisation that make this model special
class APIMeta:
pass
class MyOtherModel(models.Model):
other_field = models.IntegerField()
first_model = models.ForeignKey(MyModel, db_column='mymodel')
...
class Meta:
# basic django meta Stuff
verbose_name = 'my other model'
# the only customisation that make this model special
class APIMeta:
pass
constraints
to allow this database adaptater to work like a relational one, the API targeted must respect some requirments
dynamic-rest installed and all the serializers must provide it’s functionnality (hinerit from DynamicModelSerializer)
each serializers must :
provide the id fields
provide the related field (ManyToMany and ForeignKey on Models) as DynamicRelationField
provide the reverse related field (each ForeignKey and manyToMany add a relation on the other models. the serializer from the other model must provide the DynamicRelationField for these relation
class MenuSerializer(DynamicModelSerializer):
pizzas = DynamicRelationField('PizzaSerializer', many=True)
class Meta:
model = Menu
name = 'menu'
fields = ('id', 'code', 'name', 'pizzas')
deferred_fields = ('pizza_set', )
class PizzaSerializer(DynamicModelSerializer):
toppings = DynamicRelationField(ToppingSerializer, many=True)
menu = DynamicRelationField(MenuSerializer)
class Meta:
model = Pizza
name = 'pizza'
fields = ('id', 'name', 'price', 'from_date', 'to_date', 'toppings', 'menu')
Django rest models provide a way to check the consistency of the api with the local models via the django check framework. at each startup, it will query the api with OPTIONS to check if the local models match the remote serializers.
limitations
since this is not a real relational database, all feathure cannot be implemented. some limitations are inherited by dynamic-rest filtering system too.
aggregations : is not implemented on the api endpoint. maybe in future release
complexe filtering using OR : all filter passed to dynamic-rest is ANDed together, so no OR is possible
negated AND in filtering: a negated AND give a OR, so previous limitation apply
negated OR in filtering: since the compitation of nested filter is complexe and error prone, we disable all OR. in fact, only some nested of AND is accepted. only the final value of the Q() object can be negated
for short, you can’t :
Pizza.objects.aggregate()
Pizza.objects.annotate()
Pizza.objects.filter(Q(..) | Q(..))
Pizza.objects.exclude(Q(..) & Q(..))
Pizza.objects.exclude(Q(..) | Q(..))
but you can :
Pizza.objects.create
Pizza.objects.bulk_create
Pizza.objects.update
Pizza.objects.bulk_update
Pizza.objects.select_related
Pizza.objects.prefetch_related
Pizza.objects.values
Pizza.objects.values_list
Pizza.objects.delete
Pizza.objects.count()
Pizza.objects.filter(..., ..., ...)
Pizza.objects.filter(...).filter(...).exclude(...)
Pizza.objects.exclude(..., ...).exclude(...)
Pizza.objects.filter(Q(..) & Q(..))
specific comportments
some specific behaviour has been implemented to use the extra functionnality of a Rest API :
whene inserting, the resulting model is returned by the API. the inserted model is updated with the resulting values. this imply 2 behavior:
if you provided a default data in the api, this data will be populated into your created instance if it was missed
if the serializer have some cumputed data, its data will always be used as a replacment of the one you gave to your models. (see exemple Pizza.cost which is the sum of the cost of the toppling. after each save, its value will be updated)
support
this database api support :
select_related
order_by
only
defer
filter
exclude
delete
update
create
bulk create (with retrive of pk)
ManyToManyField
ForeignKey*
Documentation
The full documentation is at http://django-rest-models.readthedocs.org/en/latest/.
Requirements
Python 2.7, 3.4, 3.5
Django >= 1.8
Contributions and pull requests for other Django and Python versions are welcome.
Bugs and requests
If you have found a bug or if you have a request for additional functionality, please use the issue tracker on GitHub.
License
You can use this under GPLv3.
Thanks
Thanks to django for this amazing framework.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django-rest-models-1.5.0.tar.gz
.
File metadata
- Download URL: django-rest-models-1.5.0.tar.gz
- Upload date:
- Size: 53.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2932d916f97eeba1bc5ad137d7f989eff25f445b994b26364e084e996fdfc62f |
|
MD5 | e6bd34e3929d63f36b0fef6ccacdec3c |
|
BLAKE2b-256 | b0f073fac7fe2cf46837f28b01e62a51b632ede9e20982ea5a091cb0a06dbfe5 |
File details
Details for the file django_rest_models-1.5.0-py2.py3-none-any.whl
.
File metadata
- Download URL: django_rest_models-1.5.0-py2.py3-none-any.whl
- Upload date:
- Size: 45.2 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a4c68bce531f6a71f22d9aa5e4c55b4c11f367cd3f5f75352ad6823e843af9aa |
|
MD5 | 3671383afa42d37dfb12657058fe7093 |
|
BLAKE2b-256 | 4899c194b2f3629e49f600c4878ae5dab3c14d4c3ca9dad1a5db32d6bef07646 |