All Projects → cloudblue → django-rql

cloudblue / django-rql

Licence: Apache-2.0 license
Django RQL library

Programming Languages

python
139335 projects - #7 most used programming language
Dockerfile
14818 projects

Projects that are alternatives of or similar to django-rql

cryptopay-web
A payment gateway like Stripe for cryptocurrencies
Stars: ✭ 7 (-91.57%)
Mutual labels:  django-rest-framework
Dailyfresh-B2C
这是一个 ☛全栈/全端/全平台☚ 的B2C模式的电商项目, web后台基于Django2.0 + Python3.6, 前后端分离,前端使用Vue框架开发。移动端基于Flutter开发,一套代码支持Android&IOS平台。微信小程序基于mpvue框架开发。
Stars: ✭ 74 (-10.84%)
Mutual labels:  django-rest-framework
django-rest-framework-oauth
OAuth support for Django REST Framework
Stars: ✭ 52 (-37.35%)
Mutual labels:  django-rest-framework
DRF-API-Logger
An API Logger for your Django Rest Framework project.
Stars: ✭ 184 (+121.69%)
Mutual labels:  django-rest-framework
batamlawancorona api
Unofficial API of Batam Lawan Corona. Documentation and sample of use can be found at http://batamlawancoronaapi.herokuapp.com/docs/
Stars: ✭ 22 (-73.49%)
Mutual labels:  django-rest-framework
chembience
A Docker-based, cloudable platform for the development of chemoinformatics-centric web applications and microservices.
Stars: ✭ 41 (-50.6%)
Mutual labels:  django-rest-framework
QuestionTime
📚 Quora-like Single Page Application built with Django, Django REST Framework and Vue JS
Stars: ✭ 76 (-8.43%)
Mutual labels:  django-rest-framework
rnacentral-webcode
RNAcentral website source code
Stars: ✭ 23 (-72.29%)
Mutual labels:  django-rest-framework
django-rest-framework-condition
Decorators @​condition, @​last_modified and @​etag for Django Rest Framework
Stars: ✭ 26 (-68.67%)
Mutual labels:  django-rest-framework
django-rest-multitokenauth
An extension to Django-Rest-Frameworks Token Authentication, enabling a user to have multiple authorization tokens
Stars: ✭ 13 (-84.34%)
Mutual labels:  django-rest-framework
django-rest-framework-react-tutorial
Source code for Django Rest Framework + React tutorial.
Stars: ✭ 69 (-16.87%)
Mutual labels:  django-rest-framework
deploy-django
A bash script to deploy a django project for production sites.
Stars: ✭ 85 (+2.41%)
Mutual labels:  django-rest-framework
Cetus-GUI
cetus web端管理工具
Stars: ✭ 53 (-36.14%)
Mutual labels:  django-rest-framework
Django-Ionic-Integration
Section 3 of the Django + Angular + Ionic Course
Stars: ✭ 21 (-74.7%)
Mutual labels:  django-rest-framework
django-aws-template
Opinionated Django Project Template for AWS deployment
Stars: ✭ 36 (-56.63%)
Mutual labels:  django-rest-framework
linkedevents
Linked Events event database and API
Stars: ✭ 20 (-75.9%)
Mutual labels:  django-rest-framework
django todo app
python django를 활용한 웹 개발 튜토리얼! todo_app 만들기
Stars: ✭ 82 (-1.2%)
Mutual labels:  django-rest-framework
django-user-management
User management model mixins and api views.
Stars: ✭ 56 (-32.53%)
Mutual labels:  django-rest-framework
djburger
Framework for safe and maintainable web-projects.
Stars: ✭ 75 (-9.64%)
Mutual labels:  django-rest-framework
drf dynamics
Dynamic queryset and serializer setup for Django REST Framework
Stars: ✭ 26 (-68.67%)
Mutual labels:  django-rest-framework

Django RQL

pyversions PyPi Status PyPI status Docs Build Status Quality Gate Status Coverage PyPI Downloads

django-rql is the Django app, that adds RQL filtering to your application. This library is based on core lib-rql library.

RQL

RQL (Resource query language) is designed for modern application development. It is built for the web, ready for NoSQL, and highly extensible with simple syntax. This is a query language fast and convenient database interaction. RQL was designed for use in URLs to request object-style data structures.

RQL Reference

Currently supported operators

  1. Comparison (eq, ne, gt, ge, lt, le, like, ilike, search)
  2. List (in, out)
  3. Logical (and, or, not)
  4. Constants (null(), empty())
  5. Ordering (ordering)
  6. Select (select)
  7. Tuple (t)

Documentation

Full documentation is available at https://django-rql.readthedocs.org.

Example

from dj_rql.filter_cls import RQLFilterClass, RQL_NULL

from py_rql.constants import FilterLookups


class ModelFilterClass(RQLFilterClass):
    """
    MODEL - Django ORM model
    FILTERS - List of filters
    EXTENDED_SEARCH_ORM_ROUTES - List of additional Django ORM fields for search
    DISTINCT - Boolean flag, that specifies if queryset must always be DISTINCT
    SELECT - Boolean flag, that specifies if Filter Class supports select operations and queryset optimizations
    OPENAPI_SPECIFICATION - Python class that renders OpenAPI specification

    Filters can be set in two ways:
        1) string (default settings are calculated from ORM)
        2) dict (overriding settings for specific cases)

    Filter Dict Structure
    {
        'filter': str
        # or
        'namespace': str

        'source': str
        # or
        'sources': iterable
        # or
        'custom': bool
        # or
        'dynamic': bool
        'field': obj

        'lookups': set

        'qs': obj

        'use_repr': bool  # can't be used in namespaces
        'ordering': bool  # can't be true if 'use_repr=True'
        'search': bool    # can't be true if 'use_repr=True'
        'hidden': bool
    }

    """
    MODEL = Model
    FILTERS = ['id', {
        # `null_values` can be set to override ORM is_null behaviour
        # RQL_NULL is the default value if NULL lookup is supported by field
        'filter': 'title',
        'null_values': {RQL_NULL, 'NULL_ID'},
        'ordering': False,
    }, {
        # `ordering` can be set to True, if filter must support ordering (sorting)
        # `ordering` can't be applied to non-db fields
        'filter': 'status',
        'ordering': True,
    }, {
        # `search` must be set to True for filter to be used in searching
        # `search` must be applied only to text db-fields, which have ilike lookup
        'filter': 'author__email',
        'search': True,
    }, {
        # `source` must be set when filter name doesn't match ORM path
        'filter': 'name',
        'source': 'author__name',
    }, {
        # `namespace` is useful for API consistency, when dealing with related models
        'namespace': 'author',
        'filters': ['id', 'name'],  # will be converted to `author.id` and `author.name`
    },{
        # `distinct` needs to be setup for filters that require QS to work in DISTINCT mode
        # `openapi` configuration is automatically collected by OpenAPI autogenerator
        'filter': 'published.at',
        'source': 'published_at',
        'distinct': True,
        'openapi': {
            'required': True,
            'deprecated': True,
            'description': 'Good description',
            'hidden': False,  # can be set to avoid collecting by autogenerator
            # type and format are collected automatically and shouldn't be setup, in general
            'type': 'string',
            'format': 'date',
        },
    }, {
        # `use_repr` flag is used to filter by choice representations
        'filter': 'rating.blog',
        'source': 'blog_rating',
        'use_repr': True,
    }, {
        # `hidden` flag is used to set default select behaviour for associated field
        'filter': 'rating.blog_int',
        'source': 'blog_rating',
        'use_repr': False,
        'ordering': True,
        'hidden': True,
    }, {
        # We can change default lookups for a certain filter
        'filter': 'amazon_rating',
        'lookups': {FilterLookups.GE, FilterLookups.LT},
    }, {
        # Sometimes it's needed to filter by several sources at once (distinct is always True).
        # F.e. this could be helpful for searching.
        'filter': 'd_id',
        'sources': {'id', 'author__id'},
        'ordering': True,
    }, {
        # Some fields may have no DB representation or non-typical ORM filtering
        # `custom` option must be set to True for such fields
        'filter': 'custom_filter',
        'custom': True,
        'lookups': {FilterLookups.EQ, FilterLookups.IN, FilterLookups.I_LIKE},
        'ordering': True,
        'search': True,
         # Optional ORM field for query parameter value validation
        'field': IntegerField(), 

        'custom_data': [1],
    }]


from dj_rql.drf.backend import RQLFilterBackend
from dj_rql.drf.paginations import RQLContentRangeLimitOffsetPagination


class DRFViewSet(mixins.ListModelMixin, GenericViewSet):
    queryset = MODEL.objects.all()
    serializer_class = ModelSerializer
    rql_filter_class = ModelFilterClass
    pagination_class = RQLContentRangeLimitOffsetPagination
    filter_backends = (RQLFilterBackend,)

Notes

  1. Values with whitespaces or special characters, like ',' need to have "" or ''
  2. Supported date format is ISO8601: 2019-02-12
  3. Supported datetime format is ISO8601: 2019-02-12T10:02:00 / 2019-02-12T10:02Z / 2019-02-12T10:02:00+03:00
  4. Support for Choices() fields from Django Model Utilities is added
  5. Library supports caching with different strategies for queryset building, which can be very useful for collections, which use select().

Queryset execution result (filtered data) is NOT cached (!), only queryset building is cached.

from dj_rql.filter_cls import RQLFilterClass

from cachetools import LRUCache

class MyFilterClass(RQLFilterClass):
    SELECT = True
    QUERIES_CACHE_BACKEND = LRUCache
    QUERIES_CACHE_SIZE = 100

Helpers

There is a Django command generate_rql_class to decrease development and integration efforts for filtering. This command automatically generates a filter class for a given model with all relations and all optimizations (!) to the specified depth.

Example

django-admin generate_rql_class --settings=tests.dj_rf.settings tests.dj_rf.models.Publisher --depth=1 --exclude=authors,fk2

This command for the model Publisher from tests package will produce the following output to stdout:

from tests.dj_rf.models import Publisher

from dj_rql.filter_cls import RQLFilterClass
from dj_rql.qs import NSR


class PublisherFilters(RQLFilterClass):
    MODEL = Publisher
    SELECT = True
    EXCLUDE_FILTERS = ['authors', 'fk2']
    FILTERS = [
    {
        "filter": "id",
        "ordering": True,
        "search": False
    },
    {
        "filter": "name",
        "ordering": True,
        "search": True
    },
    {
        "namespace": "fk1",
        "filters": [
            {
                "filter": "id",
                "ordering": True,
                "search": False
            }
        ],
        "qs": NSR('fk1')
    }
]

Django Rest Framework Extensions

  1. Pagination (limit, offset)
  2. Support for custom fields, inherited at any depth from basic model fields, like CharField().
  3. Backend DjangoFiltersRQLFilterBackend with automatic conversion of Django-Filters query to RQL query.
  4. OpenAPI docs are autogenerated for filter classes.

Best Practices

  1. Use dj_rql.utils.assert_filter_cls to test your API view filters. If the mappings are correct and there is no custom filtering logic, then it's practically guaranteed, that filtering will work correctly.
  2. Prefer using custom=True with RQLFilterClass.build_q_for_custom_filter overriding over overriding RQLFilterClass.build_q_for_filter.
  3. Custom filters may support ordering (ordering=True) with build_name_for_custom_ordering.
  4. Django JSON fields can't be used as namespaces currently, but can be supported via dynamic=True, for example:
{
    'filter': 'json_data.key',
    'source': 'json_data__key',
    'dynamic': True,
    'field': CharField(null=True),
},

Development

  1. Python 3.6+
  2. Install dependencies requirements/dev.txt and requirements/extra.txt
  3. We use isort library to order and format our imports, and we check it using flake8-isort library (automatically on flake8 run).
    For convenience you may run isort . to order imports.

Testing

  1. Python 3.6+
  2. Install dependencies requirements/test.txt
  3. export PYTHONPATH=/your/path/to/django-rql/

Check code style: flake8 Run tests: pytest

Tests reports are generated in tests/reports.

  • out.xml - JUnit test results
  • coverage.xml - Coverage xml results

To generate HTML coverage reports use: --cov-report html:tests/reports/cov_html

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].