[Answered ]-How to fill test DB in Django with objects of models with ManyToManyFields?

1👍

Try to use the set() method to create objects for ManyToManyFields so:

def create_data(self, fields_and_names):
    data = {}
    for field_name, field_model in fields_and_names.items():
        if ('ptr' not in field_name
                and 'synonym' not in field_name
                and field_name != 'id'):
            if isinstance(field_model, CharField):
                data[field_name] = self.get_string_random()
            elif isinstance(field_model, DecimalField):
                data[field_name] = self.get_number_random()
            elif isinstance(field_model, ManyToManyField):
                choices = field_model.related_model.objects.all()
                data[field_name] = set(choices.order_by('?')[:randint(1, len(choices))])
    return data

Here, order_by('?') is used to randomly order the choices and select a random number of choices using slicing.

Edit

Try this:

from random import sample

# ...

if isinstance(field_model, ManyToManyField):
    choices = field_model.related_model.objects.all()
    count = randint(1, len(choices))
    data[field_name] = set(sample(choices, count))

Edit 2

Try to first create the object without the many-to-many relationships, then add the related objects using the set method so:


def create_data(self, fields_and_names):
    data = {}
    many_to_many_fields = []
    for field_name, field_model in fields_and_names.items():
        if ('ptr' not in field_name
                and 'synonym' not in field_name
                and field_name != 'id'):
            if isinstance(field_model, CharField):
                data[field_name] = self.get_string_random()
            elif isinstance(field_model, DecimalField):
                data[field_name] = self.get_number_random()
            elif isinstance(field_model, ManyToManyField):
                many_to_many_fields.append(field_name)
    obj = Deciduous.objects.create(**data)
    for field_name in many_to_many_fields:
        choices = [self.get_choice_random(Deciduous._meta.get_field(field_name)) for _ in range(randint(1, 3))]
        getattr(obj, field_name).set(choices)
    return data

Leave a comment