# Django ES DRF

**Work in progress**

A simple integration layer between Django, Elasticsearch and Django rest framework

## Model and ES Document example

To declare your own document, create a model and register it with
a DjangoDocument

```python
from django.db import models
from django_es_drf import registry, DjangoDocument
from rest_framework.serializers import ModelSerializer


class School(models.Model):
    name = models.CharField(max_length=100)
    address = models.TextField()


@registry.register(School)
class SchoolDocument(DjangoDocument):
    class Index:
        name = "schools"
```

If you want to split the file into models, serializers
and documents, be free to do so but ensure that the 
file including documents is loaded at the startup -
in app's ready function, imported at the bottom of the
model etc.

Later on, use `SchoolDocument` (which is a subclass of elasticsearch-dsl document):

```python
for s in SchoolDocument.search().filter('term', name='Blah'):
    print(s)
    s.name = s.name + '-test'
    s.save()  # will save django and index to ES
```

## DRF example

The simplest case is:

```python

class SchoolAPI(ESViewSet):
    document = SchoolDocument
```

### Search, facets

### Luqum search

## Django Document and mapping

### Custom declaration for fields

Any fields that are already present on the document will be keep as they are. In the example above, to set that
`name` is a `text` and not `keyword` (the default), just declare:

```python
import elasticsearch_dsl as e


@registry.register(School, SchoolSerializer)
class SchoolDocument(DjangoDocument):
    name = e.Text()

    class Index:
        name = "schools"
```

### Excluding fields

To exclude a field from the automatic generation, add it to `excluded_fields`:

```python
@registry.register(School, SchoolSerializer,
                   excluded_fields=['address'])
class SchoolDocument(DjangoDocument):
    class Index:
        name = "schools"
```

### Custom mapping between serializer fields and ES fields

Add your own mapping - the key is the DRF field type, value is a function that takes the field and context and returns ES field:
The context is an instance of `RegistrationContext`.

```python
import elasticsearch_dsl as e


@registry.register(School, SchoolSerializer,
                   mapping={
                       TextField: lambda fld, ctx: e.Keyword()
                   })
class SchoolDocument(DjangoDocument):
    class Index:
        name = "schools"
```

### Disabling the mapping

Add `generate=False` to decorator's parameters:

```python
import elasticsearch_dsl as e


@registry.register(School, SchoolSerializer,
                   generate=False)
class SchoolDocument(DjangoDocument):
    # you need to provide your own mapping here

    class Index:
        name = "schools"
```

### Relations

The framework does not generate code for relations -
if you need this, do it in serializer and add your
own mapping, or use a more complete library, such as
django-elasticsearch-dsl-drf.

## Serializer

The serializer is just a plain DRF serializer that converts
django fields to document's fields. When autogenerated mapping
is used, just use the plain empty serializer.

Note: see Relations section above if you need to serialize
relations

## Objects and nested

## Viewsets