Search code examples
pythondjangogisgeodjangofactory-boy

Using Factory Boy with GeoDjango PointFields


I'm working on writing tests for a new GeoDjango project I've started. Normally I used Factory Boy and Faker to create model instances for testing. However it's not clear to me how you can mock GeoDjango PointField fields. When looking at the record in Spacialite it appears as a binary blob.

I'm totally new to GIS stuff, and a little confused as to how I can create factories for PointFields in Django.

# models.py

from django.contrib.gis.db import models

class Place(models.Model):
    name = models.CharField(max_length=255)
    location = models.PointField(blank=True, null=True)

    objects = models.GeoManager()

    def __str__(self):
        return "%s" % self.name
# factories.py

import factory
from faker import Factory as FakerFactory
from . import models

faker = FakerFactory.create()

class PlaceFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Place

    name = factory.LazyAttribute(lambda x: faker.name())
    #location = What do I do?

Solution

  • I believe you need to create a custom fuzzy attribute for point instances. Can you try this? Right now I don't have the setup to run it all through.

    import random
    from django.contrib.gis.geos import Point
    from factory.fuzzy import BaseFuzzyAttribute
    
    class FuzzyPoint(BaseFuzzyAttribute):
        def fuzz(self):
            return Point(random.uniform(-180.0, 180.0),
                         random.uniform(-90.0, 90.0))
    
    
    class PlaceFactory(FakerFactory):
        name = factory.LazyAttribute(lambda x: faker.name())
        location = FuzzyPoint()
        class Meta:
            model = models.Place