Easily add complex search functionality to Django projects
Project description
# django-find
## Summary
**django-find** is a Django app that makes it easy to add complex
search functionality to your project. It supports two different ways
to search your Django models: Query-based, or JSON-based.
### Query-based search
By query-based, we mean that you can use statements like these
to search your model:
- `hello world` (searches all fields for hello and world)
- `author:robert OR title:road` (searches the field "author" for "robert", and "title" for "road")
- `author:"robert frost" and (title:road or chapter:2)`
- `^robert` (find anything that starts with "robert")
- `robert$` (find anything that ends with "robert")
- `^robert$ and not title:road` (find anything that equals "robert" and not the title "road")
In other words, you can write anything from super-simple text based
searches, to complex boolean logic.
### JSON-based search
To make it easy to do complex searches spanning multiple models, a
JSON-based search functionality is provided:
```
{
"Author":{"name":[[["equals","test"]]]},
"Book": {"title":[[["notcontains","c"]]]},
"Chapter": {"content":[[["startswith","The "]]]}
}
```
django-find is smart in figuring out how to join those models
together and return a useful search results.
## Example
Enabling the functionality is as simple as the following:
1. Make sure your model inherits the `Searchable` mixin. A word of
caution: Inherit from models.Model first, then Searchable.
2. Add a "find" attribute to your models, that lists the
aliases and maps them to a Django field using Django's selector
syntax (underscore-separated field names).
Example:
```python
from django.db import models
from django_find import Searchable
class Author(models.Model, Searchable):
name = models.CharField("Author Name", max_length=10)
find = [
('author', 'name'),
('name', 'name'),
]
class Book(models.Model, Searchable):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField("Title", max_length=10)
rating = models.IntegerField()
find = [
('author', 'author__name'), # Note the selector syntax
('title', 'title'),
('rating', 'rating'),
]
```
That is all, your models now provide the following methods:
```python
# Query-based search returns a standard Django QuerySet that you
# can .filter() and work with as usual.
query = Book.by_query('author:"robert frost" and title:"the road"')
# You can also get a Django Q object for the statements.
q_obj = Book.q_from_query('author:"robert frost" and title:"the road"')
# JSON-based search exhausts what Django's ORM can do, so it does
# not return a Django QuerySet, but a row-based PaginatedRawQuerySet:
query, field_list = Book.by_json_raw('''{
"Chapter": {"title":[[["contains","foo"]]]}
}''')
print('|'.join(field_list))
for row in query:
print('|'.join(row))
```
You can pass the PaginatedRawQuerySet to Django templates as you
would with a Django QuerySet, as it supports slicing and
pagination.
## Quick start
1. Add "django\_find" to your `INSTALLED_APPS` setting like this::
```python
INSTALLED_APPS = [
...
'django_find',
]
```
2. Include the django\_find URLconf in your project urls.py like this::
```python
path('django_find/', include('django_find.urls')),
```
3. Run `python manage.py migrate` to create the django\_find models.
## Summary
**django-find** is a Django app that makes it easy to add complex
search functionality to your project. It supports two different ways
to search your Django models: Query-based, or JSON-based.
### Query-based search
By query-based, we mean that you can use statements like these
to search your model:
- `hello world` (searches all fields for hello and world)
- `author:robert OR title:road` (searches the field "author" for "robert", and "title" for "road")
- `author:"robert frost" and (title:road or chapter:2)`
- `^robert` (find anything that starts with "robert")
- `robert$` (find anything that ends with "robert")
- `^robert$ and not title:road` (find anything that equals "robert" and not the title "road")
In other words, you can write anything from super-simple text based
searches, to complex boolean logic.
### JSON-based search
To make it easy to do complex searches spanning multiple models, a
JSON-based search functionality is provided:
```
{
"Author":{"name":[[["equals","test"]]]},
"Book": {"title":[[["notcontains","c"]]]},
"Chapter": {"content":[[["startswith","The "]]]}
}
```
django-find is smart in figuring out how to join those models
together and return a useful search results.
## Example
Enabling the functionality is as simple as the following:
1. Make sure your model inherits the `Searchable` mixin. A word of
caution: Inherit from models.Model first, then Searchable.
2. Add a "find" attribute to your models, that lists the
aliases and maps them to a Django field using Django's selector
syntax (underscore-separated field names).
Example:
```python
from django.db import models
from django_find import Searchable
class Author(models.Model, Searchable):
name = models.CharField("Author Name", max_length=10)
find = [
('author', 'name'),
('name', 'name'),
]
class Book(models.Model, Searchable):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField("Title", max_length=10)
rating = models.IntegerField()
find = [
('author', 'author__name'), # Note the selector syntax
('title', 'title'),
('rating', 'rating'),
]
```
That is all, your models now provide the following methods:
```python
# Query-based search returns a standard Django QuerySet that you
# can .filter() and work with as usual.
query = Book.by_query('author:"robert frost" and title:"the road"')
# You can also get a Django Q object for the statements.
q_obj = Book.q_from_query('author:"robert frost" and title:"the road"')
# JSON-based search exhausts what Django's ORM can do, so it does
# not return a Django QuerySet, but a row-based PaginatedRawQuerySet:
query, field_list = Book.by_json_raw('''{
"Chapter": {"title":[[["contains","foo"]]]}
}''')
print('|'.join(field_list))
for row in query:
print('|'.join(row))
```
You can pass the PaginatedRawQuerySet to Django templates as you
would with a Django QuerySet, as it supports slicing and
pagination.
## Quick start
1. Add "django\_find" to your `INSTALLED_APPS` setting like this::
```python
INSTALLED_APPS = [
...
'django_find',
]
```
2. Include the django\_find URLconf in your project urls.py like this::
```python
path('django_find/', include('django_find.urls')),
```
3. Run `python manage.py migrate` to create the django\_find models.
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 Distributions
No source distribution files available for this release.See tutorial on generating distribution archives.
Built Distribution
File details
Details for the file django_find-0.1-py2.py3-none-any.whl
.
File metadata
- Download URL: django_find-0.1-py2.py3-none-any.whl
- Upload date:
- Size: 25.1 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.11.1 setuptools/0.9.8 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/2.7.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9881fd40ef64d09f88b45f64ee23b014ad26ecda2c12e199a3bda99aff8316dc |
|
MD5 | f18266ec1f4f3918cefda04e30f7142a |
|
BLAKE2b-256 | 303ed4635d9865af2889548c45758d7431ac2550e694b39cfd5241f135c0eda3 |