Hi all,
I’m trying to represent a field mapping in Django and I’m getting strange duplicates when querying the mappings.
After a lot of searching, I found out that it is caused by an ordering property.
My best guess is that this causes a faulty join somewhere, but I do not fully understand it or what I should have done instead.
Could someone please explain me this behaviour?
class RejiMapping(models.Model):
class Meta:
#This causes the duplicates
ordering = ["from_fields__name"]
#
from_fields = models.ManyToManyField(RejiMappingField, related_name="mapping_tables_from", through='RejiMappingMappingFromField')
to_fields = models.ManyToManyField(RejiMappingField, related_name="mapping_tables_to", through='RejiMappingMappingToField')
description = models.TextField(default="", blank=True)
class RejiMappingField(models.Model):
class Meta:
ordering = ['name']
name = models.CharField(max_length=60, null=False, blank=False, unique=True)
description = models.TextField(default="", blank=True)
class RejiMappingMappingField(models.Model):
class Meta:
ordering = ["id"]
unique_together = ("mapping", "field",)
abstract=True
mapping = models.ForeignKey(RejiMapping,
on_delete=models.CASCADE,
verbose_name=_("Mapping"))
field = models.ForeignKey(RejiMappingField,
on_delete=models.CASCADE,
verbose_name=_("Field"))
class RejiMappingMappingFromField(RejiMappingMappingField):
pass
class RejiMappingMappingToField(RejiMappingMappingField):
pass
class TestRejiMapping(TestCase):
def setUp(self):
f1 = RejiMappingField.objects.create(name="Field1")
f2 = RejiMappingField.objects.create(name="Field2")
f3 = RejiMappingField.objects.create(name="Field3")
mapping = RejiMapping.objects.create()
mapping.from_fields.add(f1, f2)
mapping.to_fields.add(f3)
def test_mapping_model(self):
self.assertEqual(2, RejiMappingMappingFromField.objects.all().count())
self.assertEqual(1, RejiMappingMappingToField.objects.all().count())
self.assertEqual(1, RejiMapping.objects.all().count())
self.assertEqual(RejiMapping.objects.all().count(), len(RejiMapping.objects.all()))
FAIL: test_mapping_model (reji_app.models.tests.test_reji_mapping_model.TestRejiMappingTable)
----------------------------------------------------------------------
Traceback (most recent call last):
self.assertEqual(RejiMapping.objects.all().count(), len(RejiMapping.objects.all()))
AssertionError: 1 != 2
----------------------------------------------------------------------
Ran 1 test in 0.013s
FAILED (failures=1)
Destroying test database for alias 'default'...
The weird thing is that the duplicate only occurs when I retrieve a full QuerySet using all()
, as soon as I use a count(), filter() or order_by(), the duplicates disappear.