GeoDjango - всплывающее окно с листовкой для внешнего ключа

Я пытаюсь показать имя пользователя во всплывающем окне с помощью Leaflet. Прямо сейчас я могу вернуть идентификатор/pk внешнего ключа только в виде числа, но я хотел бы показать фактическое имя пользователя во всплывающем окне. (поле имени в модели правильно отображается во всплывающем окне)

Вот простая модель

class Reserve(gis_models.Model):
    geom    = gis_models.PolygonField()
    objects = gis_models.GeoManager()
    user = models.ForeignKey(User)
    name = models.CharField(max_length = 240)

Просмотры

def reserve_datasets(request):
    reserve= serialize('geojson', Reserve.objects.all())
    return HttpResponse(reserve, content_type='json')

HTML

<script type="text/javascript">

              function our_layers(map,options){
                var all_reserve_datasets = new L.GeoJSON.AJAX("{% url 'reserve_datasets'%}",{
                    onEachFeature: function(feature,layer){

                    layer.bindPopup('<h4> Name: '+feature.properties.name+'</h4><p>User: '+feature.properties.user);

                    },
                });

                all_applied_reserve.addTo(map);
              }

        </script>

        {%  leaflet_map "gis" callback="window.our_layers" %}


person Geoffrey Nyaga    schedule 23.01.2018    source источник


Ответы (1)


Встроенный сериализатор geojson может сериализовать только поля модели. Попробуйте это, чтобы сериализовать другие атрибуты в ваших моделях:

class BetterGeoJsonSerializer(Serializer):

    def _init_options(self):
        self.extra_attrs = self.options.pop('extra_attrs', ())
        super()._init_options()

    def get_dump_object(self, obj):
        d = super().get_dump_object(obj)
        for attr in self.extra_attrs:
            v = obj
            for s in attr.split("."):
                v = getattr(v, s)
            d[attr] = v
        return d


def to_geojson(queryset, extra_attrs=(), **options):
    s = BetterGeoJsonSerializer()
    s.serialize(queryset, extra_attrs=extra_attrs, **options)
    return s.getvalue()

# ...

def reserve_datasets(request):
    extra = ('user.username',)
    reserve= to_geojson(Reserve.objects.all(), extra)
    return HttpResponse(reserve, content_type='application/json')

Вы также можете использовать это для сериализации свойств:

class Reserve(models.Model):
    geom = models.PolygonField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=240)

    @property
    def xxx(self):
        return 12345

    @property
    def user_info(self):
        return {'id': self.user.id, 'name': self.user.username, 'email': self.user.email}

с помощью extra = ('user_info', 'xxx') в вашем представлении.

Для сложных сериализаций рассмотрите возможность использования Django REST Framework.

person Udi    schedule 24.01.2018