我如何伪造一个多边形场?
How Can I Fake A MultiPolygon Field?
我正在为包含 MultiPolygonField 的模型创建 Django 工厂。当我 运行 测试时它抛出错误。详情如下。
我创建了一个特殊的提供程序来伪造这个字段。代码取自 Django 文档:
from django.contrib.gis.geos import (
Polygon,
MultiPolygon,
)
import factory
from faker import Faker
from faker.providers import BaseProvider
fake = Faker()
class Provider(BaseProvider):
def mpoly(self):
p1 = Polygon( ((0, 0), (0, 1), (1, 1), (0, 0)) )
p2 = Polygon( ((1, 1), (1, 2), (2, 2), (1, 1)) )
mpoly = MultiPolygon(p1, p2)
return mpoly
fake.add_provider(Provider)
class GeographyFactory(factory.DjangoModelFactory):
"""
A Factory to generate mock GeographyFactory objects to be used
in tests.
"""
class Meta:
model = 'location.Geography'
name = factory.Faker('name')
mpoly = fake.mpoly
然而,当我 运行 测试时遇到的错误让我很困惑。
TypeError: Cannot set Geography SpatialProxy (MULTIPOLYGON) with value of type: <class 'method'>
这似乎表明我没有返回正确的类型,但我无法弄清楚它想要什么而不是我返回的 MultiPolygon 对象。
为什么它认为我要返回 <class 'method'>
?
欢迎提出任何建议!
我建议定义一个自定义模糊属性,这将允许您的测试具有一定的随机性。
import factory
import factory.fuzzy
from factory import random
class FuzzyPolygon(factory.fuzzy.BaseFuzzyAttribute):
"""Yields random polygon"""
def __init__(self, length=None, **kwargs):
if length is None:
length = random.randgen.randrange(3, 20, 1)
if length < 3:
raise Exception("Polygon needs to be 3 or greater in length.")
self.length = length
super().__init__(**kwargs)
def get_random_coords(self):
return (
factory.Faker("latitude").generate({}),
factory.Faker("longitude").generate({}),
)
def fuzz(self):
prefix = suffix = self.get_random_coords()
coords = [self.get_random_coords() for __ in range(self.length - 1)]
return Polygon([prefix] + coords + [suffix])
class FuzzyMultiPolygon(factory.fuzzy.BaseFuzzyAttribute):
"""Yields random multipolygon"""
def __init__(self, length=None, **kwargs):
if length is None:
length = random.randgen.randrange(2, 20, 1)
if length < 2:
raise Exception("MultiPolygon needs to be 2 or greater in length.")
self.length = length
super().__init__(**kwargs)
def fuzz(self):
polygons = [FuzzyPolygon().fuzz() for __ in range(self.length)]
return MultiPolygon(*polygons)
然后您可以在 DjangoModelfactory
;
中使用这些
class GeographyFactory(factory.DjangoModelFactory):
"""
A Factory to generate mock GeographyFactory objects to be used
in tests.
"""
class Meta:
model = 'location.Geography'
name = factory.Faker('name')
mpoly = FuzzyMultiPolygon()
我正在为包含 MultiPolygonField 的模型创建 Django 工厂。当我 运行 测试时它抛出错误。详情如下。
我创建了一个特殊的提供程序来伪造这个字段。代码取自 Django 文档:
from django.contrib.gis.geos import (
Polygon,
MultiPolygon,
)
import factory
from faker import Faker
from faker.providers import BaseProvider
fake = Faker()
class Provider(BaseProvider):
def mpoly(self):
p1 = Polygon( ((0, 0), (0, 1), (1, 1), (0, 0)) )
p2 = Polygon( ((1, 1), (1, 2), (2, 2), (1, 1)) )
mpoly = MultiPolygon(p1, p2)
return mpoly
fake.add_provider(Provider)
class GeographyFactory(factory.DjangoModelFactory):
"""
A Factory to generate mock GeographyFactory objects to be used
in tests.
"""
class Meta:
model = 'location.Geography'
name = factory.Faker('name')
mpoly = fake.mpoly
然而,当我 运行 测试时遇到的错误让我很困惑。
TypeError: Cannot set Geography SpatialProxy (MULTIPOLYGON) with value of type: <class 'method'>
这似乎表明我没有返回正确的类型,但我无法弄清楚它想要什么而不是我返回的 MultiPolygon 对象。
为什么它认为我要返回 <class 'method'>
?
欢迎提出任何建议!
我建议定义一个自定义模糊属性,这将允许您的测试具有一定的随机性。
import factory
import factory.fuzzy
from factory import random
class FuzzyPolygon(factory.fuzzy.BaseFuzzyAttribute):
"""Yields random polygon"""
def __init__(self, length=None, **kwargs):
if length is None:
length = random.randgen.randrange(3, 20, 1)
if length < 3:
raise Exception("Polygon needs to be 3 or greater in length.")
self.length = length
super().__init__(**kwargs)
def get_random_coords(self):
return (
factory.Faker("latitude").generate({}),
factory.Faker("longitude").generate({}),
)
def fuzz(self):
prefix = suffix = self.get_random_coords()
coords = [self.get_random_coords() for __ in range(self.length - 1)]
return Polygon([prefix] + coords + [suffix])
class FuzzyMultiPolygon(factory.fuzzy.BaseFuzzyAttribute):
"""Yields random multipolygon"""
def __init__(self, length=None, **kwargs):
if length is None:
length = random.randgen.randrange(2, 20, 1)
if length < 2:
raise Exception("MultiPolygon needs to be 2 or greater in length.")
self.length = length
super().__init__(**kwargs)
def fuzz(self):
polygons = [FuzzyPolygon().fuzz() for __ in range(self.length)]
return MultiPolygon(*polygons)
然后您可以在 DjangoModelfactory
;
class GeographyFactory(factory.DjangoModelFactory):
"""
A Factory to generate mock GeographyFactory objects to be used
in tests.
"""
class Meta:
model = 'location.Geography'
name = factory.Faker('name')
mpoly = FuzzyMultiPolygon()