Git Product home page Git Product logo

django-dynamic-fixture's Introduction

Django Dynamic Fixture

Docs Status PyPI version PyPI - Python Version PyPI - Downloads

Latest version: 4.0.1 (Sep 2023)

Django Dynamic Fixture (DDF) is a complete and simple library to create dynamic model instances for testing purposes.

It lets you focus on your tests, instead of focusing on generating some dummy data which is boring and polutes the test source code.

Basic Examples

Customize only the important details of the test:

    from ddf import G
    from my_library import Author, Book

    def test_search_book_by_author():
        author1 = G(Author)
        author2 = G(Author)
        book1 = G(Book, authors=[author1])
        book2 = G(Book, authors=[author2])
        books = Book.objects.search_by_author(author1.name)
        assert book1 in books
        assert book2 not in books

Using some goodies to keep the test code smaller:

    from ddf import G

    def test_search_book_by_author():
        author1, author2 = G('my_library.Author', n=2)
        book1 = G('my_library.Book', authors=[author1])
        book2 = G('my_library.Book', authors=[author2])
        books = Book.objects.search_by_author(author1.name)
        assert book1 in books
        assert book2 not in books

Configuring data from relationship fields:

    from ddf import G

    def test_search_book_by_author():
        book1 = G(Book, main_author__name='Eistein')
        book2 = G(Book)
        books = Book.objects.search_by_author(book1.main_author.name)
        assert book1 in books
        assert book2 not in books
        assert book1.main_author.name == 'Eistein'

Cheat Sheet

# Import the main DDF features
from ddf import N, G, F, M, C, P, teach # meaning: New, Get, ForeignKey, Mask, Copier, Print, teach
# `N` creates an instance of model without saving it to DB
instance = N(Book)
# `G` creates an instance of model and save it into the DB
instance = G(Book)
# `F` customize relationship objects
instance = G(Book, author=F(name='Eistein'))
# Same as `F`
instance = G(Book, author__name='Eistein')
# `M` receives a data mask and create a random string using it
# Known symbols: `_`, `#` or `-`
# To escape known symbols: `!`
instance = N(Book, address=M('Street ___, ### !- --'))
assert instance.address == 'Street TPA, 632 - BR'
# `C` copies data from one field to another
instance = N(Book, address_formatted=C('address'), address=M('Street ___, ### \- --'))
assert instance.address_formatted == 'Street TPA, 632 - BR'
# `teach` teaches DDF in how to build an instance
teach(Book, address=M('Street ___, ### !- --'))
instance = G(Book)
assert instance.address == 'Street TPA, 632 - BR'
# `P` print instance values for debugging
P(instance)
import ddf
ddf.__version__
from ddf import ddf_check_models
succeeded, errors = ddf_check_models()
succeeded, errors = ddf_check_models(print_csv=True)
succeeded, errors = ddf_check_models(csv_filename='ddf_compatibility_report.csv')

django-dynamic-fixture's People

Contributors

7mp avatar cailloumajor avatar cmltawt0 avatar codelahoma avatar dmrz avatar drmartiner avatar drtyrsa avatar gregmuellegger avatar heyman avatar jayvdb avatar jmurty avatar julienaubert avatar k4rl85 avatar mrmachine avatar mrweeble avatar paulocheque avatar pobybolek avatar qris avatar raphaelkimmig avatar saxix avatar sjhewitt avatar sobolevn avatar timgates42 avatar valdergallo avatar vinzd avatar vparitskiy avatar wesleykendall avatar zanderle avatar zvictor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-dynamic-fixture's Issues

Can we change persist_dependencies to False by default on N?

According to https://github.com/paulocheque/django-dynamic-fixture/blob/master/django_dynamic_fixture/__init__.py#L71 and the docs, persist_dependencies is True by default for the N function. Almost 100% of time in our code we have to type persist_dependencies=False, and it's cumbersome to have to manually review code and ensure people aren't accidentally hitting the DB when they instantiate in-memory models.

My question - can this default behavior be changed? If it's too backwards breaking, can I add an M function that is N with persist_dependencies=False?

null=True, blank=True fields are given values unless default=None

I have a model with this field:

reset_timestamp = models.DateTimeField(null=True, blank=True)

To my surprise, DDF sets this field with a date when instantiating the model. I was expecting it to leave it blank, because it can be, and that's what Django would do, even though it doesn't explicitly set default=None. I had to do that to avoid this happening:

reset_timestamp = models.DateTimeField(null=True, blank=True, default=None)

Is this supposed to be happening? Should I be including explicit defaults in all my nullable fields?

Relation Not Created For Reverse Many To One Managers

With models like such:

class User(models.Model):
   name = models.CharField(max_length=100)

class Comment(models.Model):
   text = models.TextField()
   user = models.ForeignKey(User, related_name="comments")

I would hope that I could run G(User, comments=[F(), F()]) to make a user with a few test comments.

However, this creates a user, but creates no comments.

G(Comment, user=F()) creates a comment, and a user.

The solution is to do

x = G(User)
comments = [G(Comment), G(Comment)]
x.comments.set(comments)

But this seems extraneous when F() exists for a reason. Would there be a way to make it so reverse relation managers behave the same way that a regular relation manager works?

Custom data fixture for specific field on a model

I think it would be really useful to be able to define custom data fixtures for specific fields on a model. So for example, say I have a following model

class Book(models.Model):
    title = models.CharField(max_length=255)
    number_of_pages = models.IntegerField()

I would want to define special behavior for data generation for field number_of_pages, for example data fixture for number_of_pages could be random between [10,100]. It's different than what already exists in DDF in that it's specific to a model field vs a field in general (http://django-dynamic-fixture.readthedocs.org/en/latest/data_fixtures.html#custom-field-fixture).
It would be useful to be able to set something like this.

Allow propagation of ignored_fields to automatically generated Foreign Key

Hi, i have some problem with the integration between django-polymorphic and django-dynamic-fixtures.

This was talked in different issues and some fix has been done like #85.
The problem for me is the automatic generation of a foreign key releated to a polymorphic instance.

The solution suggested in #85 is to set DDF_IGNORE_FIELDS = ['*_ptr'] but this solution is ineffective in my case, because the DDF code does not use ignored_fields with an auto generated related object.

Example:

# settings.py
DDF_IGNORE_FIELDS = ['*_ptr']

# models.py
class Location(PolymorphicModel):
    objects = PolymorphicManager()

class Country(Location):
    name = models.CharField(max_length=200)

class Publisher(models.Model):
    country = models.ForeignKey(Country, null=True, blank=True)

# test.py
from django_dynamic_fixture import G

G(Country)  # <-- no problem
G(Publisher)  # <-- raise Attribution error

The error generated in 2nd call is caused by the implicit creation of a Country for the Publisher instance.
The ignored fields are not correctly set for the publisher country because it receive an empty ignored_fields.

I wonder if there is a reason to avoid this propagation, i will prepare a PR to fix it if is not needed.

Carlo

Doesn't work properly with django-hvad for translations

This works with django-hvad, provided that you give values for all required fields:

    item1 = NewsItem.objects.create(title="Item One",
        publication_date=date.today())

But this doesn't:

    item2 = G(NewsItem, title="Another One")

Because the title attribute is a translated field. I'm not sure whether the problem is in hvad or DDF. I think it occurs here, in DynamicFixture.new():

for field in get_fields_from_model(model_class):
    ...
    self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)

Because get_fields_from_model doesn't return translated fields (they're not in model_class._meta.fields either):

(Pdb) p get_fields_from_model(model_class)
[<django.db.models.fields.AutoField: id>,
<django.db.models.fields.DateField: publication_date>,
<django.db.models.fields.files.ImageField: photo>,
<django.db.models.fields.CharField: image_caption>, 
<django.db.models.fields.CharField: location>]

That may be a mistake by hvad, but you can actually assign to those fields:

(Pdb) p instance.title
u''
(Pdb) instance.title = 'hello'
(Pdb) p instance.title
'hello'

so if DynamicFixture would actually assign all supplied kwargs, then it would work with hvad. Additionally it would not ignore supplied values for fields that it doesn't know about, which can lead to subtle errors.

Grammar mistakes in docs

I've noticed many grammar mistakes in the docs. It's not a priority at all, but I can do a pull-request if you want.

Problem with ManyToManyField

Having added a ManyToManyField to a model (MyModel) I am suddenly starting to get these kind of errors:

G(MyModel)
{ instance is printed here ... }
AttributeError: 'MyModel' object has no attribute 'id'

The error message itself isn't very helpful, do you have any idea what is going on?

Creating files for ImageField and FileField fields

I'm writing custom fixture class for creating uploaded files. But this code must be in a package.

import os

from django.conf import settings
from django.core.files import images, File

from django_dynamic_fixture.\
    fixture_algorithms.sequential_fixture import SequentialDataFixture


image_path = os.path.join(settings.PROJECT_ROOT, 'static', 'images',
                          'logo.png')


class FixedFilesFixture(SequentialDataFixture):

    def filepathfield_config(self, field, key):
        return image_path

    def filefield_config(self, field, key):
        with open(image_path, 'rb+') as fh:
            return File(fh)

    def imagefield_config(self, field, key):
        with open(image_path, 'rb+') as fh:
            return images.ImageFile(fh)

Argument called `instance` can't be passed to object creation with G

Argument called instance can't be passed to object creation with G.
I have a class with instance field and there is a name collision in

self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)

Whole traceback:

In [12]: G(AdminInstanceRole, instance=instance, admin=admin, role=role)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-edd08ece1c23> in <module>()
----> 1 G(AdminInstanceRole, instance=instance, admin=admin, role=role)

/usr/local/lib/python2.7/dist-packages/django_dynamic_fixture/__init__.pyc in get(model, shelve, n, **kwargs)
    104     d = fixture(**kwargs)
    105     if n == 1:
--> 106         return d.get(model, shelve=shelve, **kwargs)
    107     instances = []
    108     for _ in range(n):

/usr/local/lib/python2.7/dist-packages/django_dynamic_fixture/ddf.pyc in get(self, model_class, shelve, named_shelve, **kwargs)
    514         :named_shelve: restore configuration saved in DDF library with a name.
    515         """
--> 516         instance = self.new(model_class, shelve=shelve, named_shelve=named_shelve, **kwargs)
    517         if is_model_abstract(model_class):
    518             raise InvalidModelError(get_unique_model_name(model_class))

/usr/local/lib/python2.7/dist-packages/django_dynamic_fixture/ddf.pyc in new(self, model_class, shelve, named_shelve, persist_dependencies, **kwargs)
    441             if is_key_field(field) and 'id' not in configuration: continue
    442             if field.name in self.ignore_fields: continue
--> 443             self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
    444         number_of_pending_fields = len(self.pending_fields)
    445         # For Copier fixtures: dealing with pending fields that need to receive values of another fields.

TypeError: set_data_for_a_field() got multiple values for keyword argument 'instance'

Thanks.

Problem with django-filer

I'm running Django 1.8.2 with django-filer 0.9.10 and django-dynamic-fixture 1.8.4. I have an example model like this:

from django.db import models
from filer.fields.image import FilerImageField

class Animal(models.Model):
    name = models.CharField(max_length=100)
    picture = FilerImageField(null=True, blank=True)

Using the get function in my unit tests, like so:

G(Animal)

I get this traceback:

Creating test database for alias 'default'...
E
======================================================================
ERROR: test_animal (animals.tests.AnimalTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/matt/projects/ddf-bug/animals/tests.py", line 8, in test_animal
    instance = G(Animal)
  File "/home/matt/...trimed.../django_dynamic_fixture/__init__.py", line 106, in get
    return d.get(model, shelve=shelve, **kwargs)
  File "/home/matt/...trimed.../django_dynamic_fixture/ddf.py", line 528, in get
    instance = self.new(model_class, shelve=shelve, named_shelve=named_shelve, **kwargs)
  File "/home/matt/...trimed.../django_dynamic_fixture/ddf.py", line 455, in new
    self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
  File "/home/matt/...trimed.../django_dynamic_fixture/ddf.py", line 366, in set_data_for_a_field
    data = self._process_field_with_default_fixture(__field, model_class, persist_dependencies)
  File "/home/matt/...trimed.../django_dynamic_fixture/ddf.py", line 351, in _process_field_with_default_fixture
    data = self._process_foreign_key(model_class, field, persist_dependencies)
  File "/home/matt/...trimed.../django_dynamic_fixture/ddf.py", line 334, in _process_foreign_key
    data = fixture.get(next_model)
  File "/home/matt/...trimed.../django_dynamic_fixture/ddf.py", line 528, in get
    instance = self.new(model_class, shelve=shelve, named_shelve=named_shelve, **kwargs)
  File "/home/matt/...trimed.../django_dynamic_fixture/ddf.py", line 455, in new
    self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
  File "/home/matt/...trimed.../django_dynamic_fixture/ddf.py", line 383, in set_data_for_a_field
    setattr(__instance, __field.name, data) # Model.field = data
AttributeError: can't set attribute

----------------------------------------------------------------------
Ran 1 test in 0.014s

FAILED (errors=1)
Destroying test database for alias 'default'...

As a short term fix until I get a chance to look into this more I've added all of the FilerImageField fields I have to DDF_IGNORE_FIELDS in my Django settings, i.e.

DDF_IGNORE_FIELDS = ['picture',]

If a ForeignKey has a pk as its default value rather than an instance, dynamic fixtures break

I have a model like this (heavily simplified):

class City(models.Model):
    currency = models.ForeignKey('payment.Currency', default=2)

If I try to create a city fixture using G(City), it fails because it attempts to assign 2 as the value of currency, rather than the instance of Currency with primary key 2

I think the solution is alter _process_field_with_default_fixture to return the foreign key's model if there's a default value that's not an instance or callable.

Admittedly, using defaults on relationship fields is a yucky, which we'll hopefully remove in the long run, but we'd like to be able to use DDF before then.

Improve Documentation about setUp and tearDown for tests

Currently the documentation does not talk of how setUp and tearDown methods for classes work.
If possible, include optimization of setUp and tearDown as well.

A simple example would be as follows:

class BookModelTest(TestCase):

     def setUp(self):
          self.author = G(Author)
          self.book = G(Book, author=[author])

     def test_book_creation(self):
          book_in_db = Book.objects.all()
          self.assertEquals(book_in_db.count(), 1)
          first_book = book_in_db[0]
          self.assertEquals(first_book.name, self.book.name)
          self.assertEquals(list(first_book.author), [self.author])

class Author(models.Model):

     name = models.CharField(max_length=100)

class Book(models.Model):

     name = models.CharField(max_length=100)
     author = models.ManyToManyField(Author)

BadDataError: IntegrityError

I have a data fixture which extends SequentialDataFixture. The fixture is given below:

class ASequentialDataFixture(SequentialDataFixture):
   def genericipaddressfield_config(self, field, key):
        return "{}.{}.{}".format(randint(000,999), randint(000,999), randint(000,999))

I have following test code.

        tokens = [G(Token, data_fixture = ASequentialDataFixture()).token for count in range(100)]

Which generates following error.

Traceback (most recent call last):
  File "/home/suren/job/ussd/core/tests/test_models.py", line 33, in test_generates_unique_tokens
    tokens = [G(Token, data_fixture = ASequentialDataFixture()).token for count in range(100)]

...

BadDataError: ('panel.models.user.User', IntegrityError(1062, "Duplicate entry '[email protected]' for key 'email'"))

Generate model instance that contains custom fields

I have a model contains ListField(custom field) like this:

class CalendarField(models.TextField):
     __metaclass__ = models.SubfieldBase 
     ...
    def to_python(self, value):
         if isinstance(value, list) or value is None:
            return value
         return [int(e) for e in value.split(self.token)]

class MyModel(models.Model):
    calendar = CalendarField()

When i use G() method to create instance:

m = G(MyModel, calendar=[1, 2, 3])

It always failed when executing to_python. After some debuging , i found that DDF filled calendar field with " " instead of [1, 2, 3].

So, my question is:
How to fill custom field in G()?

I have looked over the document and tried several approaches, but they didn't help.

Python 3.5: type hints for N() and G() outputs

Hey,

I know that the support for new Python is not there yet, so I'm not making it a PR. Instead I put here how it can be achieved to have type hints for N() and G() functions (super useful for using the lib with an IDE that uses type hints).

In __init__.py, at the top:

import typing

(...)

INSTANCE_TYPE = typing.TypeVar('INSTANCE')

Then:

def new(model: typing.Type[INSTANCE_TYPE], shelve=False, n=1, persist_dependencies=True, **kwargs) -> INSTANCE_TYPE:
def get(model: typing.Type[INSTANCE_TYPE], shelve=False, n=1, **kwargs) -> INSTANCE_TYPE:

DDF_VALIDATE_ARGS should default to DEBUG

Hi,

I just activated DDF_VALIDATE_ARGS in one of my projects and immediately found some bugs. It should probably default to whatever value DEBUG is set to, so that problems can be detected as early as possible.

The code says that the current default is False for compatibility reasons, but maybe it could be changed it in the next major version?

Support for django.contrib.postgres.fields.JSONField

Just wondering if this is in the roadmap supporting this field? Currently I am getting

django_dynamic_fixture.ddf.UnsupportedFieldError: core.models.Invoice.raw_data (django.contrib.postgres.fields.jsonb.JSONField)

Please release a new version containing Django 1.9 support

Hi, django-dynamic-fixture has support for Django 1.9 since the merge of #74.

But there is no PyPI release yet, I would love to see a new official support so we can finally use this package in a Django 1.9 project.

Is there any chance there will be a new release in the next weeks?

PyPI release

It seems the most recent PyPI release (which claims to be Python 3 compatible) is from March, but there have been some essential Python 3 related fixes since then (a couple months ago), with no release.

I have started a project using Django 1.7 and Python 3.4 and would really love to use django-dynamic-fixture without having to point my requirements file at a GitHub URL.

Set max number of instances per model_class?

I need the ability to set the maximum number of instances per model_class, is there a way to do this already?

The the django project I'm using this for is large and complex with lots of relationships every where and I cannot find an easy way to minimise the creating of many instances per model class.

InvalidConfigurationError when creating an object with a primary key

Tests fall when trying to create objects with a primary key.
Sample Models and Test

# models.py
class Course(models.Model):
    name = models.CharField(max_length=20)


class Lesson(models.Model):
    name = models.CharField(max_length=20)


class CourseLesson(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE)

# test.py
def test_create_course_lesson():
    course = G(Course)
    lesson = G(Lesson)

    lesson_course = G(CourseLesson, course=course, lesson=lesson)

    assert lesson_course.id is not None

I get an error

============================================================================================= FAILURES ==============================================================================================
_____________________________________________________________________________________ test_create_course_lesson _____________________________________________________________________________________

    def test_create_course_lesson():
        course = G(Course)
        lesson = G(Lesson)
    
>       lesson_course = G(CourseLesson, course=course, lesson=lesson)

home/tests.py:10: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
<string>:6: in get
    ???
../env/dj3/lib/python3.8/site-packages/django_dynamic_fixture/__init__.py:142: in _get
    return d.get(model, lesson=lesson, **kwargs)
../env/dj3/lib/python3.8/site-packages/django_dynamic_fixture/ddf.py:585: in get
    instance = self.new(model_class, lesson=lesson, **kwargs)
../env/dj3/lib/python3.8/site-packages/django_dynamic_fixture/ddf.py:477: in new
    configuration = self._configure_params(model_class, lesson, **kwargs)
../env/dj3/lib/python3.8/site-packages/django_dynamic_fixture/ddf.py:457: in _configure_params
    configuration_custom = library.get_configuration(model_class, name=lesson)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <django_dynamic_fixture.ddf.DDFLibrary object at 0x1080f5ee0>, model_class = <class 'home.models.CourseLesson'>, name = <Lesson: Lesson object (1)>

    def get_configuration(self, model_class, name=None):
        if name is None:
            name = self.DEFAULT_KEY
        # copy is important because this dict will be updated every time in the algorithm.
        config = self.configs.get(model_class, {})
        if name != self.DEFAULT_KEY and name not in config.keys():
>           raise InvalidConfigurationError('There is no lesson for model %s with the name "%s"' % (get_unique_model_name(model_class), name))
E           django_dynamic_fixture.ddf.InvalidConfigurationError: There is no lesson for model home.models.CourseLesson with the name "Lesson object (1)"

../env/dj3/lib/python3.8/site-packages/django_dynamic_fixture/ddf.py:221: InvalidConfigurationError

django 3.0.2
django-dynamic-fixture 3.0.1
pytest 5.3.2
pytest-django 3.7.0

On version django-dynamic-fixture 2.0.0 everything works fine

Object creation fails if a ForeignKey field has an ID as default

I'm using f5784b, and I've a model with this field:

GENERIC_BUNNY_ID = 8
# ...
bunny_type = models.ForeignKey(BunnyType, default=GENERIC_BUNNY_ID)

When I try to instantiate this using G, I get:

File "/usr/local/lib/python2.6/dist-packages/django_dynamic_fixture-1.6.3-py2.6.egg/django_dynamic_fixture/ddf.py", line 370, in set_data_for_a_field
    setattr(instance, field.name, data) # Model.field = data
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/related.py", line 331, in __set__
    self.field.name, self.field.rel.to._meta.object_name))
ValueError: Cannot assign "8": "Asset.category" must be a "Category" instance.

I've not looked super long at the code, but I'll submit a pull request for code that's got it working for me.

Toby

Set DDF_IGNORE_FIELDS or ignore_fields argument using wild cards

Hi.

It would be nice to set DDF_IGNORE_FIELDS or ignore_fields argument using wild cards.

You could want to ignore a set of fields in one or more models.

By example, when I start using this app on my unit tests, I always get AttributeError on polymorphic models. This exception is documented on django-polymorphic documentation.

To workaorund this, I had to set all fields that ends with "_ptr" to be ignored.

It would be nice to be able to set DDF_IGNORE_FIELDS = ['*_ptr'].

Just one suggestion.

Best regards,
Roger

`get_or_create` and `update_or_create` support?

I'd like to be able to specify some unique combination of fields to G (or F) and have DDF try to get the matching object and either update or create... I imagine it working like this:

# get by `a` and `b`, or create with `a`, `b` and `c`.
G(a='abc', b='def', c='ghi', _get=['a', 'b'])

# get by `a` and `b` and update `c`, or create with `a`, `b` and `c`.
G(a='abc', b='def', c='ghi', _update=['a', 'b'])

I want to use DDF with a custom management function to quickly populate test data to play with interactively (not in a test case).

Using the default sequential data fixture I quickly run into integrity errors. Using the random data fixture I might avoid them briefly, but still quickly run into problems.

Adding get_or_create and update_or_create support I could safely re-run my management command any time to create missing or update existing test data.

Unusually named primary key fields don't work.

class SampleModel(models.Model):
    sample_model_id = models.AutoField(primary_key=True)
    some_data = models.TextField()

...

def some_function():
    s = G(SampleModel, sample_model_id=1234, some_data='abcd')
    assert s.sample_model_id == 1
    assert s.some_data == 'abcd'

I have the above model, and when I run some_function the assert statements pass.

G() doesn't set data

account = G(Account, bank_account='12-3109-0024210-000')
print account.bank_account, 111111111

prints 111111111

using Django 1.7

Changing value of auto_now_add and _auto_now on field

My tests started failing today due to a database consistency error on a datetime field when trying to instantiate a model. After a bit of debugging I noticed that the auto_now_add attribute on this field was changing from True to False at some point in the code.

I managed to track it down to get() call for the model, after a bit of digging I found the following function which seems to be the culprit:

https://github.com/paulocheque/django-dynamic-fixture/blob/master/django_dynamic_fixture/ddf.py#L265

Is there any reason for this? Seems like this would completely break most models that run through it with auto_now_add or auto_now set.

(Thanks for the great project by the way, code is so much cleaner (was using Model.objects.create() before :( )

`ForeignKey(null=True)` with no default specified should not be auto filled?

I have a bunch of models with ForeignKey fields that can be null and which have no default value specified. DDF always tries to auto fill these fields when I use G(). I end up having to constantly do G(foo=None, ...) to stop it, or put a redundant ForeignKey('Foo', default=None, null=True) in my model.

DDF should only auto fill fields that are required to pass model validation?

Bug with `__` notation and foreign keys?

I have General, with a OneToOneField to Pod, and Pod.type can be ['gallery', 'general', ...], and Pod.broadcast is a ForeignKey to Broadcast.

In my tests, first I create broadcast, then I want to create General (and other objects) and specify that pod__broadcast=broadcast and pod__type='general' (or other types).

But DDF wants to either use "gallery" (first option for Pod.type) or create new Broadcast objects.

# I can use __ to set pod__type.
>>> G(models.General, pod__type='general').pod.type
'general'

# But if I also set pod__broadcast, DFF re-uses my broadcast, but my specified pod__type is ignored and DFF uses the first option.
>>> G(models.General, pod__broadcast=broadcast, pod__type='general').pod.type
'gallery'
>>> G(models.General, pod__broadcast=broadcast, pod__type='general').pod.broadcast, broadcast
(<Broadcast: 1-ea6e254fd42; 2>, <Broadcast: 1-ea6e254fd42; 2>)

# If I mix F() with __ notation, I get opposite but equally weird results. pod__type is correct, but a new Broadcast is created.
>>> G(models.General, pod=F(broadcast=broadcast), pod__type='general').pod.type
'general'
>>> G(models.General, pod=F(broadcast=broadcast), pod__type='general').pod.broadcast, broadcast
(<Broadcast: 12-35ff32184f; 13>, <Broadcast: 1-ea6e254fd42; 2>)

# If I use only F(), it works.
>>> G(models.General, pod=F(broadcast=broadcast, type='general')).pod.type
'general'
>>> G(models.General, pod=F(broadcast=broadcast, type='general')).pod.broadcast, broadcast
(<Broadcast: 1-ea6e254fd42; 2>, <Broadcast: 1-ea6e254fd42; 2>)

If mixing F() with __ is not supported, it should raise an error, although having it work would be nice.

However, it looks like there is definitely something wrong with __.

SECRET_KEY not set

I can't run tests without adding a dummy value for SECRET_KEY in settings.py. Is there something I have configured incorrectly, or is this a bug?

UnsupportedFieldError: PointField [geoDjango]

Hi,

I realized that DDF has no compatibility with geodjango, more specifically with django.contrib.gis.db.models.fields.PointField.
I am interested in implement it, but I don't know how to start. How can we deal with geodjango requirement, and how am I supposed to test the implementation? Any ideas how can we do it?

BinaryField support?

class Entity(models.Model):
    text = models.BinaryField()

G(Entity)  # raise UnsupportedFieldError.

in Django1.6.1

DDFImproperlyConfigured DDF_DEFAULT_DATA_FIXTURE

My settings file is at project_root/settings/client/dev.py and the fixture file is at project_root/libs/fixtures.py'

My DDF configuration is given below.
DDF_DEFAULT_DATA_FIXTURE = 'libs.fixtures.ASequentialDataFixture'

During test I get following error.
ERROR: Failure: DDFImproperlyConfigured (DDF_DEFAULT_DATA_FIXTURE (libs.fixtures.ASequentialDataFixture) must be 'sequential', 'static_sequential', 'global_sequential', 'random' or 'path.to.CustomDataFixtureClass'.)

Add support for string as model name in G, N

I'm using this monkey patched version of G that accepts app_name.ClassName string format similar to how you would use in models.ForeignKey().

from django_dynamic_fixture import G as __G

def G(model, **kwargs):
    """Overrides the G to be able to use it with 'app_name.model_name'
    format as well.

    >>> G('users.User', email="[email protected]")
    <User: [email protected]>
    >>> G(User, email="[email protected]")
    <User: [email protected]>
    """

    if isinstance(model, str):
        from django.apps import apps
        model = apps.get_model(model)
    return __G(model, **kwargs)

I think it would be a nice backward-compatible add-on to the library itself. @paulocheque thoughts? I'll submit a PR.

No support for uuid fields in django 1.8

Like in the title,

Trying to G(ModelName) with uuid field results in

    raise(UnsupportedFieldError(get_unique_field_name(field)))
UnsupportedFieldError: apps.testapp.models.SomeModel.uuid_field

Steps to reproduce:

  1. create a model (eg SomeModel) with models.UUIDField (eg uuid_field)
  2. open ./manage.py shell
  3. do G(SomeModel)

Thanks,

Remove created files

If i create a test, and use the dynamic fixture on a model that contains a FileField, it creates a file, and after the test ends the created file is not removed from the file system.

Could you add some way to remove those images?

DDF setup plugin doesn't work when using Buildout

My project currently uses Buildout and I haven't tested with a virtualenv-based project. But I noticed the DDF setup plugin actually imports the ddf_setup of the DDF setup plugin since django-dynamic-fixture appears first in sys.path.

Not quite sure what the best solution is to this yet.

GEOS "Point" expects (longitude, latitude)

GeoDjango's "Point" class expects the constructor arguments to be (longitude, latitude) rather than the more traditional (latitude, longitude). Inverting them results in some unexpected behaviour & validation errors.

Fix is likely just to switch the arguments in fixture_algorithms/default_fixture.py:

class GeoDjangoDataFixture(object):
    def create_point(self, x=None, y=None):
        # latitude: [-90,90], longitude: [-180,180]
        latitude = x or random.randint(-90, 90)
        longitude = y or random.randint(-180, 180)
        return Point(longitude, latitude)

Bug using SimpleUploadedFile

Was implemented one new library in django to create tests files called SimpleUploadedFile

The problem happen when you try send one SimpleUploadedFile to create one file instance.

Traceback (most recent call last):
  File "/vagrant/goal_design/tests/test_views.py", line 24, in test_download_documentation
    is_last_version="true")
  File "/home/vagrant/.virtualenvs/env/local/lib/python2.7/site-packages/django_dynamic_fixture/__init__.py", line 106, in get
    return d.get(model, shelve=shelve, **kwargs)
  File "/home/vagrant/.virtualenvs/env/local/lib/python2.7/site-packages/django_dynamic_fixture/ddf.py", line 528, in get
    instance = self.new(model_class, shelve=shelve, named_shelve=named_shelve, **kwargs)
  File "/home/vagrant/.virtualenvs/env/local/lib/python2.7/site-packages/django_dynamic_fixture/ddf.py", line 455, in new
    self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
  File "/home/vagrant/.virtualenvs/env/local/lib/python2.7/site-packages/django_dynamic_fixture/ddf.py", line 372, in set_data_for_a_field
    if django_file.file.mode != 'rb':
AttributeError: '_io.BytesIO' object has no attribute 'mode'

And in my tests, Im using

from django.core.files.uploadedfile import SimpleUploadedFile


BASE_FILE = SimpleUploadedFile('test_upload.txt', 'these are the file contents')
G(DjangoFIleModel, file=BASE_FILE)

data_fixture='random' doesn't work

The docs say you can do:

G(MyModel, data_fixture='random')

But this doesn't work:

Traceback (most recent call last):
File "/home/installuser/projects/inaspsite/django/website/perireg/tests/accept_reject_application_for_resource_tests.py", line 213, in test_reapprove_updated_registration_form_loads_with_all_fields_changed
    new_inst = new(Institution, data_fixture='random')
File "/home/installuser/projects/inaspsite/django/website/.ve/local/lib/python2.7/site-packages/django_dynamic_fixture/__init__.py", line 79, in new
    return d.new(model, shelve=shelve, persist_dependencies=persist_dependencies, **kwargs)
File "/home/installuser/projects/inaspsite/django/website/.ve/local/lib/python2.7/site-packages/django_dynamic_fixture/ddf.py", line 441, in new
    self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
File "/home/installuser/projects/inaspsite/django/website/.ve/local/lib/python2.7/site-packages/django_dynamic_fixture/ddf.py", line 348, in set_data_for_a_field
    data = self._process_field_with_default_fixture(field, model_class, persist_dependencies)
File "/home/installuser/projects/inaspsite/django/website/.ve/local/lib/python2.7/site-packages/django_dynamic_fixture/ddf.py", line 335, in _process_field_with_default_fixture
    data = self.data_fixture.generate_data(field)
AttributeError: 'str' object has no attribute 'generate_data'

I suspect I should be creating an instance of RandomDataFixture() instead?

UnsupportedFieldError on GenericIPAddressField

I have a GenericIPAddressField in a model.

Believing django-dynamic-fixture currently doesn't support it. I wrote a fixture for it.

DDF_FIELD_FIXTURES = {
    'django.db.models.GenericIPAddressField': {'ddf_fixture': lambda: "{}.{}.{}".format(randint(000,999), randint(000,999), randint(000,999))},
}

But it still complains about it. How to fix this?

Django 1.11.1 GDALException: Could not find the GDAL library

From Django 1.11.1 if django.contrib.gis is imported it will not fail silently if GDAL is not installed. This will make django-dynamic-fixture to trows errors for projects which does not use django.contrib.gis and there is no GDAL isntalled.

    from django_dynamic_fixture import G, F
  File "/usr/local/lib/python2.7/site-packages/django_dynamic_fixture/__init__.py", line 10, in <module>
    from django_dynamic_fixture.fixture_algorithms.sequential_fixture import SequentialDataFixture, \
  File "/usr/local/lib/python2.7/site-packages/django_dynamic_fixture/fixture_algorithms/sequential_fixture.py", line 12, in <module>
    from django.contrib.gis.geos import *
  File "/usr/local/lib/python2.7/site-packages/django/contrib/gis/geos/__init__.py", line 5, in <module>
    from .collections import (  # NOQA
  File "/usr/local/lib/python2.7/site-packages/django/contrib/gis/geos/collections.py", line 11, in <module>
    from django.contrib.gis.geos.geometry import GEOSGeometry, LinearGeometryMixin
  File "/usr/local/lib/python2.7/site-packages/django/contrib/gis/geos/geometry.py", line 11, in <module>
    from django.contrib.gis import gdal
  File "/usr/local/lib/python2.7/site-packages/django/contrib/gis/gdal/__init__.py", line 28, in <module>
    from django.contrib.gis.gdal.datasource import DataSource
  File "/usr/local/lib/python2.7/site-packages/django/contrib/gis/gdal/datasource.py", line 39, in <module>
    from django.contrib.gis.gdal.driver import Driver
  File "/usr/local/lib/python2.7/site-packages/django/contrib/gis/gdal/driver.py", line 5, in <module>
    from django.contrib.gis.gdal.prototypes import ds as vcapi, raster as rcapi
  File "/usr/local/lib/python2.7/site-packages/django/contrib/gis/gdal/prototypes/ds.py", line 9, in <module>
    from django.contrib.gis.gdal.libgdal import GDAL_VERSION, lgdal
  File "/usr/local/lib/python2.7/site-packages/django/contrib/gis/gdal/libgdal.py", line 44, in <module>
    'GDAL_LIBRARY_PATH in your settings.' % '", "'.join(lib_names)
GDALException: Could not find the GDAL library (tried "gdal", "GDAL", "gdal1.11.0", "gdal1.10.0", "gdal1.9.0", "gdal1.8.0", "gdal1.7.0"). Try setting GDAL_LIBRARY_PATH in your settings.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.