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
Source:stackexchange.com