Sjoerd van Poelgeest Sjoerd van Poelgeest - 1 month ago 7
Python Question

django factory boy test gives __str__ returned non-string

I'm adjusting tests to use factory boy instances instead of models.objects.create(..)

It's going well, but now I've run into an error and I can't seem to find the source. Can anyone help?

models.py

class Regelset(models.Model): # todo: statussen?
# todo: koppeling productiebestanden
# todo: xml inlezen

bon = models.ForeignKey(Bon)
toepassing = models.ForeignKey(Toepassing)
product = models.ForeignKey(Product)

naam = models.CharField(max_length=500, blank=True, help_text="naam")
originelen = models.DecimalField(max_digits=20, decimal_places=0, null=True, blank=True, help_text="originelen")
oplage = models.DecimalField(max_digits=20, decimal_places=0, null=True, blank=True, help_text="oplage")

breedte_in_cm = models.DecimalField(max_digits=20, decimal_places=3, null=True, blank=True,
help_text="breedte in cm")
hoogte_in_cm = models.DecimalField(max_digits=20, decimal_places=3, null=True, blank=True, help_text="hoogte in cm")

# bedoeld om een extra formaat door te geven (bedoeld voor Repro items)
breedte_in_cm2 = models.DecimalField(max_digits=20, decimal_places=3, null=True, blank=True,
help_text="breedte in cm")
hoogte_in_cm2 = models.DecimalField(max_digits=20, decimal_places=3, null=True, blank=True,
help_text="hoogte in cm")

strekkende_meters = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True)
korting = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True)
korting_invoer = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True, help_text="korting")
type_korting = models.CharField(max_length=50, choices=MenusGlobals.type_korting_choices, blank=True,
help_text="type korting")
# nesting is een samengesteld veld van de printregel en mediaregel wat gezet wordt. Queries gaan niet over een
# berekend veld
nesting = models.CharField(max_length=500, blank=True)

omslag_dubbelzijdig = models.BooleanField(help_text="omslag dubbelzijdig", default=False)
binnenwerk_dubbelzijdig = models.BooleanField(help_text="binnenwerk dubbelzijdig", default=False)
binnenwerk_kleur = models.BooleanField(help_text="binnenwerk kleur", default=False)
omslag_kleur = models.BooleanField(help_text="omslag kleur", default=False)

def __str__(self):
return self.naam

def get_verkoopprijs_ex_kort(self):
return self.sum_gerelateerde_regelwaardes('verkoopprijs_ex_kort')

def get_verkoopprijs_ex_kort_incl_productprijs(self):
return self.sum_gerelateerde_regelwaardes('verkoopprijs_ex_kort_incl_productprijs')

def get_verkoopprijs_incl_kort(self):
return self.sum_gerelateerde_regelwaardes('verkoopprijs_incl_kort')

def get_basisprijs(self):
return self.sum_gerelateerde_regelwaardes('basisprijs')

def get_korting(self):
return self.sum_gerelateerde_regelwaardes('korting')

def get_aantal(self):
return self.originelen * self.oplage

def get_oppervlakte_m2_per_stuk(self):
if self.toepassing.afmeting_verplicht():
return self.breedte_in_cm / 100 * self.hoogte_in_cm / 100
return 0

def sum_gerelateerde_regelwaardes(self, fieldname):
# ondersteunende functie om alle getallen vanuit een veld uit de regel tabel bij elkaar op te tellen
waardelijst = self.regel_set.all().aggregate(models.Sum(fieldname)) # output = {'<fieldname>_sum': waarde}
return invoer_is_check_is_value(waardelijst.get('{0}__sum'.format(fieldname)), check=None, value=0)


Factories.py

import factory
from . import models


class ArtikelFactory(factory.DjangoModelFactory):
class Meta:
model = models.Artikel


class ToepassingFactory(factory.DjangoModelFactory):
class Meta:
model = models.Toepassing


class ToepassingRegelFactory(factory.DjangoModelFactory):
class Meta:
model = models.ToepassingsRegel

toepassing = factory.SubFactory(ToepassingFactory)


class ProductFactory(factory.DjangoModelFactory):
class Meta:
model = models.Product

toepassing = factory.SubFactory(ToepassingFactory)


class RelatieFactory(factory.DjangoModelFactory):
class Meta:
model = models.Relatie

firmanaam = "Nepper"
code = "neppe"


class ProjectFactory(factory.DjangoModelFactory):
class Meta:
model = models.Project

relatie = factory.SubFactory(RelatieFactory)


class BonFactory(factory.DjangoModelFactory):
class Meta:
model = models.Bon

project = factory.SubFactory(ProjectFactory)


class RegelsetFactory(factory.DjangoModelFactory):
class Meta:
model = models.Regelset

bon = factory.SubFactory(BonFactory)
product = factory.SubFactory(ProductFactory)
naam = "naam"
get_oppervlakte_m2_per_stuk = factory.PostGenerationMethodCall('get_oppervlakte_m2_per_stuk')
get_aantal = factory.PostGenerationMethodCall('get_aantal')


Tests.py

from django.test import TestCase

from decimal import Decimal

from .nesting import Nesting, FormaatError
from .import factories


class NestingTests(TestCase):
def setUp(self):
self.regelsetlijst = [factories.RegelsetFactory.create(naam="naam", originelen=1, oplage=3, breedte_in_cm=50, hoogte_in_cm=50),
factories.RegelsetFactory.create(naam="naam", originelen=1, oplage=1, breedte_in_cm=50, hoogte_in_cm=200),
factories.RegelsetFactory.create(naam="naam", originelen=1, oplage=1, breedte_in_cm=100, hoogte_in_cm=100)]


def test_get_nesting_1_vel(self):
self.assertEqual(Nesting(self.regelsetlijst, 1.37, 50, 0.5, maak_html=False).start_nesting(), (round(Decimal(3.52), 2), round(Decimal(2.75), 2)))

def test_get_nesting_formaaterror(self):
self.assertEqual(Nesting(self.regelsetlijst, 1.37, 2.5, 0.5, maak_html=False).start_nesting(), FormaatError)

def test_get_nesting_2_vel(self):
self.assertEqual(Nesting(self.regelsetlijst, 1.37, 3, 0.5, maak_html=False).start_nesting(), (round(Decimal(4.51), 2), round(Decimal(2.75), 2)))


Traceback:

Error
Traceback (most recent call last):
File "C:\Users\SjoerdvanPoelgeest\Desktop\systeem\calculator\test_nesting.py", line 11, in setUp
self.regelsetlijst = [factories.RegelsetFactory.create(naam="naam", originelen=1, oplage=3, breedte_in_cm=50, hoogte_in_cm=50),
File "C:\Python34\lib\site-packages\factory\base.py", line 558, in create
attrs = cls.attributes(create=True, extra=kwargs)
File "C:\Python34\lib\site-packages\factory\base.py", line 400, in attributes
force_sequence=force_sequence,
File "C:\Python34\lib\site-packages\factory\containers.py", line 228, in build
return stub.__fill__()
File "C:\Python34\lib\site-packages\factory\containers.py", line 83, in __fill__
res[attr] = getattr(self, attr)
File "C:\Python34\lib\site-packages\factory\containers.py", line 105, in __getattr__
val = val.evaluate(self, self.__containers)
File "C:\Python34\lib\site-packages\factory\containers.py", line 160, in evaluate
containers=containers,
File "C:\Python34\lib\site-packages\factory\declarations.py", line 298, in evaluate
return self.generate(sequence, obj, create, defaults)
File "C:\Python34\lib\site-packages\factory\declarations.py", line 385, in generate
return subfactory.simple_generate(create, **params)
File "C:\Python34\lib\site-packages\factory\base.py", line 645, in simple_generate
return cls.generate(strategy, **kwargs)
File "C:\Python34\lib\site-packages\factory\base.py", line 612, in generate
return action(**kwargs)
File "C:\Python34\lib\site-packages\factory\base.py", line 558, in create
attrs = cls.attributes(create=True, extra=kwargs)
File "C:\Python34\lib\site-packages\factory\base.py", line 400, in attributes
force_sequence=force_sequence,
File "C:\Python34\lib\site-packages\factory\containers.py", line 228, in build
return stub.__fill__()
File "C:\Python34\lib\site-packages\factory\containers.py", line 85, in __fill__
self.__log_ctx, utils.log_pprint(kwargs=res),
File "C:\Python34\lib\site-packages\factory\utils.py", line 119, in log_pprint
for key, value in kwargs.items()
File "C:\Python34\lib\site-packages\factory\utils.py", line 119, in <listcomp>
for key, value in kwargs.items()
File "C:\Python34\lib\site-packages\factory\utils.py", line 103, in _safe_repr
obj_repr = repr(obj)
File "C:\Python34\lib\site-packages\django\db\models\base.py", line 496, in __repr__
u = six.text_type(self)
TypeError: __str__ returned non-string (type NoneType)

Answer

try

def __str__(self):
    return '%s' % self.naam
Comments