Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fields are not filled #9

Closed
arnaudlimbourg opened this issue Oct 8, 2015 · 6 comments
Closed

Fields are not filled #9

arnaudlimbourg opened this issue Oct 8, 2015 · 6 comments

Comments

@arnaudlimbourg
Copy link
Contributor

I'm having trouble using the package overall.

If we take the user model, it doesn't seem to want to save any other parameter than the username.

e.g:

factory.make(
    'users.User',
    fields={
        'username': lambda n,f:f.user_name(),'city':lambda n,f:f.city()
    }
)

It does create a user but it has no city, just a blank string :( It is a custom user model for info.

I tried with another model but it keeps wanting to fill a slug which does not exist on this model.

ValueError: Cant generate a value for field `slug`
@fcurella
Copy link
Owner

fcurella commented Oct 8, 2015

Hi think I've fixed the blank string issue. Does v1.0.3 fixes the issue for you?

Re: slug: Could you paste a full traceback?

@arnaudlimbourg
Copy link
Contributor Author

I tested #8 and it does indeed fill the fields.

Traceback is:

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in make(self, model, fields, pre_save, post_save, seed, quantity)
    132             return [self.make_one(model, fields, pre_save, post_save, seed, i) for i in range(quantity)]
    133         else:
--> 134             return self.make_one(model, fields, pre_save, post_save, seed)
    135
    136 factory = Factory()

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in make_one(self, model, fields, pre_save, post_save, seed, iteration)
    119             post_save = []
    120
--> 121         instance = self.build_one(model, fields, pre_save, seed, make_fks=True, iteration=iteration)
    122         instance.save()
    123

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in build_one(self, model, fields, pre_save, seed, make_fks, iteration)
     73                 value = evaluator.evaluate(fields[field_name])
     74             else:
---> 75                 value = evaluator.fake_value(model_field)
     76
     77             if model_field.choices:

/.virtualenvs/ferpection/src/django-fakery/django_fakery/values.py in fake_value(self, field)
     37     def fake_value(self, field):
     38         if isinstance(field, models.ForeignKey):
---> 39             return self.factory.make_one(get_related_model(field), iteration=self.iteration)
     40
     41         if field.name in field_mappings.mappings_names:

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in make_one(self, model, fields, pre_save, post_save, seed, iteration)
    119             post_save = []
    120
--> 121         instance = self.build_one(model, fields, pre_save, seed, make_fks=True, iteration=iteration)
    122         instance.save()
    123

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in build_one(self, model, fields, pre_save, seed, make_fks, iteration)
     73                 value = evaluator.evaluate(fields[field_name])
     74             else:
---> 75                 value = evaluator.fake_value(model_field)
     76
     77             if model_field.choices:

/.virtualenvs/ferpection/src/django-fakery/django_fakery/values.py in fake_value(self, field)
     37     def fake_value(self, field):
     38         if isinstance(field, models.ForeignKey):
---> 39             return self.factory.make_one(get_related_model(field), iteration=self.iteration)
     40
     41         if field.name in field_mappings.mappings_names:

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in make_one(self, model, fields, pre_save, post_save, seed, iteration)
    119             post_save = []
    120
--> 121         instance = self.build_one(model, fields, pre_save, seed, make_fks=True, iteration=iteration)
    122         instance.save()
    123

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in build_one(self, model, fields, pre_save, seed, make_fks, iteration)
     73                 value = evaluator.evaluate(fields[field_name])
     74             else:
---> 75                 value = evaluator.fake_value(model_field)
     76
     77             if model_field.choices:

/.virtualenvs/ferpection/src/django-fakery/django_fakery/values.py in fake_value(self, field)
     37     def fake_value(self, field):
     38         if isinstance(field, models.ForeignKey):
---> 39             return self.factory.make_one(get_related_model(field), iteration=self.iteration)
     40
     41         if field.name in field_mappings.mappings_names:

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in make_one(self, model, fields, pre_save, post_save, seed, iteration)
    119             post_save = []
    120
--> 121         instance = self.build_one(model, fields, pre_save, seed, make_fks=True, iteration=iteration)
    122         instance.save()
    123

/.virtualenvs/ferpection/src/django-fakery/django_fakery/faker_factory.py in build_one(self, model, fields, pre_save, seed, make_fks, iteration)
     73                 value = evaluator.evaluate(fields[field_name])
     74             else:
---> 75                 value = evaluator.fake_value(model_field)
     76
     77             if model_field.choices:

/.virtualenvs/ferpection/src/django-fakery/django_fakery/values.py in fake_value(self, field)
     45             return self.evaluate_fake(field_mappings.mappings_types[field.__class__], field)
     46
---> 47         raise ValueError('Cant generate a value for field `%s`' % field.name)

ValueError: Cant generate a value for field `slug`

My model does not have a slug, though one of the foreign key does.

@fcurella
Copy link
Owner

fcurella commented Oct 8, 2015

Odd, I've tried the same scenario (a model with a FK to a model with a SlugField) and the tests are passing.

From the stacktrace looks like the build process is crossing a FK relationship 3 times (values.py@L39). Do you have any recursive or circular FKs?

@arnaudlimbourg
Copy link
Contributor Author

After a bit of digging I think I understand why there is an issue but I don't know how to solve it.

I have two models both using AutoSlug like so

from autoslug import AutoSlugField

def populate(self):
    if hasattr(self, "title"):
        return self.title
    else:
        return self.name


class AnotherModel(models.Model):
    name = models.CharField(max_length=40)
    slug = AutoSlugField(populate_from=populate)


class AModel(models.Model):
    title = models.CharField(max_length=40)
    another_model = models.ForeignKey(AnotherModel)
    slug = AutoSlugField(populate_from=populate)

When trying to fake AModel, it fails with

myapp.AnotherModel.slug

From my understanding, the code in values.py tries to create the model when encountering a foreign key

if isinstance(field, models.ForeignKey):
    return self.factory.make_one(get_related_model(field), iteration=self.iteration)

Since it does not know what to do with an autoslug it fails.

It can be solved for the first model by defining the slug but I don't see a way to do that for the related model.

# This call works
myModel = factory.make(
    'myapp.AnotherModel',
    fields={
        'title': lambda n, f: f.name(),
        'slug': lambda n, f: f.word(),
        }
    )

# This call fails
factory.make(
    'myapp.AModel',
    fields={
        'title': lambda n, f: f.name(),
        'slug': lambda n, f: f.word(),
        'another_model': myModel
        }
    )

I have tried blueprints with no success.

@fcurella
Copy link
Owner

fcurella commented Oct 9, 2015

I see a couple of bugs here:

  1. Field values passed to ForeignKeys are ignored
  2. Field class mapping is based on strict equal, when it should be based on isinstance check.

@arnaudlimbourg
Copy link
Contributor Author

Nice, just tested and it worked. Thank you!

🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants