I need a way to be able to enter an unspecified number of arbitrary, integer values with an auto-incrementing key into a dictionary in a django model.
It would need to look, or at least function, like this:
{
"1":6,
"2":10,
"3":0,
...
"n":42
}
I'm hoping there will be a simple solution like:
class Foo(models.Model):
title = models.CharField(max_length=100)
dictOfInts = {
models.AutoField(): models.IntegerField,
models.AutoField(): models.IntegerField,
models.AutoField(): models.IntegerField
...
# it would start with just one and automatically add more k-v pairs as nessary
}
#other fields ect
def __str__(self):
return self.title
Unfortunately, I know that doesn't work and wouldn't function how the comment suggests, but it would need to act like that for the end-user.
I've looked through the docs and the only workaround I found there was using models.JSONField()
, but that requires you to type out the dict yourself, which is not ideal. Another possible way that I found would be to separate the dict and the k-v pairs, linking them with a foreign key, but I couldn't quite figure out how to integrate it and it seemed very messy even if I could.
If you need any more info, just let me know.
Any help is much appreciated, thanks.
Edit: Also to note, I am currently using the admin page to enter items at the moment, but it will eventually be handled from the frontend (react), just in case that changes anything.
CodePudding user response:
Option 1, solution with JSONField:
class AJsonModel(models.Model):
name = models.CharField(null=True, max_length=255)
data = models.JSONField(null=True)
def __str__(self):
return f"A list of {[n for n in self.data]}"
data = [10, 20, 30, 40, 50]
dict_data = {k:v for (k, v) in enumerate(data, 1)}
m = AJsonModel.objects.create(name="One", data=dict_data)
m.save()
Unfortunately for this method, you will have to do some work everytime you want to add another value to the list:
c = AJsonModel.objects.get(id=1)
values = list(c.data.values())
values.append(60)
c.data = {k:v for (k, v) in enumerate(values, 1)}
c.save()
Option 2, use related table:
class AJsonModelWithChild(models.Model):
name = models.CharField(null=True, max_length=255)
def __str__(self):
return f"{self.name}"
class GrowingChild(models.Model):
value = models.IntegerField(default=0)
parent = models.ForeignKey(AJsonModelWithChild, on_delete=models.CASCADE)
def __str__(self):
return f"{self.id}: {self.value}"
The good thing for this method is that you do not have to think about the other, previous values stored before - just add a new child for this parent:
parent = AJsonModelWithChild.objects.create(name="Two")
parent.save()
child = GrowingChild.objects.create(value=100, parent=parent)
child.save()