django-elasticsearch-dsl NestedField not syncing with database

Viewed 54

I've created a django-elasticsearch-dsl document with NestedField but for some reason data for this NestedField is not fetched from the database, even though data is fetched from the base model. Mapping for index is also correct including the nested field:

{
  "mappings": {
    "properties": {
      "addresses": {
        "type": "nested",
        "properties": {
          "pk": {
            "type": "integer"
          },
          "postal_code": {
            "type": "text"
          },
          "street_name": {
            "type": "text"
          },
          "street_no": {
            "type": "integer"
          }
        }
      },
      "country": {
        "type": "text"
      },
      "name": {
        "type": "text"
      }
    }
  }
}

I did everything according to the official docs, I don't know what am I missing.

models.py

from django.db import models

# Create your models here.
class City(models.Model):
    name = models.CharField(max_length=100)
    country = models.CharField(max_length=100)

    def __str__(self):
        return f"{self.name}, {self.country}"


class Address(models.Model):
    city = models.ForeignKey(
        City, on_delete=models.CASCADE, related_name="related_city"
    )
    street_name = models.CharField(max_length=300)
    street_no = models.PositiveIntegerField()
    postal_code = models.CharField(max_length=6)

    def __str__(self):
        return f"{self.street_name} {self.street_no} ({self.city.name})"

documents.py

from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
from .models import City, Address


@registry.register_document
class CityDocument(Document):
    addresses = fields.NestedField(
        properties={
            "street_name": fields.TextField(),
            "street_no": fields.IntegerField(),
            "postal_code": fields.TextField(),
            "pk": fields.IntegerField(),
        }
    )

    class Index:
        name = "cities"

    class Django:
        model = City
        fields = ["name", "country"]
        related_models = [Address]

    def get_queryset(self):
        return super().get_queryset().prefetch_related("addresses")

    def get_instances_from_related(self, related_instance):
        if isinstance(related_instance, Address):
            return related_instance.city

1 Answers

Can you try to add .all()

def get_instances_from_related(self, related_instance):
    if isinstance(related_instance, Address):
        return related_instance.city.all()
Related