Search code examples
djangodjango-fixtures

Standard way to load initial (and ongoing) data into Django


Suppose I have a model with a field that restricts another model. For example, a Thing whose name has to be in the current set of AllowedThingNames. The set of allowed_thing_names changes (infrequently) by an external source. I have code to get that external source and create AllowedThingNames as needed.

Here is some code:

models.py:

class AllowedThingName(models.Model):
  name = models.CharField(max_length=100, unique=True)

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

  def __save__(self, *args, **kwargs):
    if AllowedThingName.objects.filter(name=self.name).exists():
      return super().save(*args, **kwargs)
    return None

tasks.py:

@shared_task
def import_new_names():
  response = request.get("some/external/url/where/allowed/names/are/listed")
  new_names = clever_way_of_parsing_response(response.content)
  for new_name in new_names:
    AllowedThingName.objects.get_or_create(name=new_name)

I have created a fixture of AllowedThingNames and I run the loaddata command at startup.

I'm not sure what the best way is to keep the set of AllowedThingNames up-to-date, though.

One solution is to periodically (via a task, or a cronjob, or whatever) call the import_new_names function above and then call dumpdata to overwrite the fixture. This will save it in the db and make sure that it gets re-loaded the next time the project restarts.

Does anybody in StackOverflow-Land have any better ideas?


Solution

  • Have you considered creating a ForeignKey relationship between Thing and AllowedThingName? Something along the lines of

    class AllowedThingName(models.Model):
      name = models.CharField(max_length=100, unique=True)
    
    class Thing(models.Model):
      name = models.ForeignKey(AllowedThingName, on_delete=models.CASCASE)