0

In my django app I have a model:

class Entry(BaseModel):
    event_name = models.CharField(_('Event name'), max_length=256, null=True, blank=True)
    slug = models.SlugField(null=True, blank=True, max_length=512)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = self.get_slug()
         super().save(*args, **kwargs)

    def get_slug(self):
        add = 1
        slug = None
        if not self.slug and self.event_name:
            init_slug = slugify.slugify(self.event_name)
            slug_available = Entry.objects.filter(slug=init_slug).count() == 0

            if slug_available:
                slug = init_slug
            else:
                while not slug_available:
                    check_slug = '{}-{}'.format(init_slug, add)
                    slug_available = Entry.objects.filter(slug=check_slug).count() == 0
                    if slug_available:
                        slug = check_slug
                    else:
                        add += 1
            return slug

    def make_slug(self):
        if not self.slug:
            slug = self.get_slug()
            self.slug = slug
            self.save()

slug field is empty by default, and now I want to update 700k+ rows with empty slug with new value.

I was doing it by querying the database: qs = Entry.objects.filter(slug__isnull=True) and then I was updating items in loop one by one:

for entry in qs:
    entry.make_slug()

but I am looking for more efficient way to do it. Do you know any simple solution?

dease
  • 2,975
  • 13
  • 39
  • 75
  • I don’t think you can use a single update statement because of the uniqueness check. I’m also not sure you can run a function like slugify within an F expression which you’d need. An approach you could take is to calculate this on the fly if it isn’t set and set a job to update it in database as needed. – bryan60 Feb 12 '20 at 20:06
  • You might get a speedup by fetching Entries in batches (based on event name?), setting the new slug values, and writing back with bulk update. Also, work within a transaction. Answers here describe both https://stackoverflow.com/questions/36751395/update-multiple-objects-at-once-in-django – nigel222 Feb 13 '20 at 09:06

0 Answers0