3

I'm trying to create a slug field in django that requires the use of 2 table fields from 2 different tables.

What is the best way of going about this?

For example: If I had a Restaurant table with a restaurant_name field and a Location table with a location_name field, how do I create a slug field from these two values? That is, a slugfield generated from restaurant_name + location_name

EDIT:

If possible, I would like to use AutoSlug Field in the solution. For example here is an implementation with a single field to slugify:

class Cuisine(models.Model):
    name = models.CharField(max_length=100)
    name_slug = AutoSlugField(populate_from='name', unique=True, null=True)
    def __str__(self):
        return self.name
Michael Smith
  • 3,307
  • 5
  • 25
  • 43

1 Answers1

3

This is simple, you don't really have to write some special handler for you AutoSlugField.

from django.utils.text import slugify


class Restaurant(models.Model):
    name = models.CharField(max_length=100)
    location = models.ForeignKey(Location)
    name_slug = models.AutoSlugField(populate_from='name', unique=True, null=True)

    def save(self, *args, **kwargs):
         '''
         Assuming that you don't have a slug field on your other model
         This will simply add the extra slug to your restaurant name.
         Personally, i would also add a slug field to the location table so you 
         simply call location.slug and don't have to slugify()
         '''
        self.name_slug += slugify(self.location.name)
        super(Restaurant, self).save(*args, **kwargs)

One thing to keep in mind here is that the django-autoslug doesn't mention anything about special max_length to their AutoSlugField, there will probably be problems with max_length for this field.

So an alternative solution is way simpler than the above:

from django.utils.text import slugify


class Restaurant(models.Model):
    name = models.CharField(max_length=100)
    location = models.ForeignKey(Location)
    # sum both fields max_length for the slug
    name_slug = models.SlugField(max_length=200, unique=True, null=True)

    def save(self, *args, **kwargs):
        # just check if name or location.name has changed
        self.name_slug = '-'.join((slugify(self.name), slugify(self.location.name)))
        super(Restaurant, self).save(*args, **kwargs)

p.s: you can make an edit with the right model names.

HassenPy
  • 2,083
  • 1
  • 16
  • 31
  • 1
    Won't this keep adding to `self.name_slug` after every save because of the `self.name_slug += ...`? – Mike Covington Jun 16 '15 at 20:49
  • thanks, i specified it in a comment, i make so much assumptions – HassenPy Jun 16 '15 at 20:59
  • In addition to changing `+=` to `=`, you'd probably want `'-'.join((slugify(self.name), slugify(self.location.name)))`. – Mike Covington Jun 16 '15 at 21:02
  • why didn't your name appear in the edit? i just improved it by changing the ```+=``` to ```=``` – HassenPy Jun 16 '15 at 21:11
  • That's weird. Not sure. I did get a notification of +2 for the edit. – Mike Covington Jun 16 '15 at 21:13
  • Wont this bug out if there is restaurant with multiple locations in the same city? The location.name is just the city and state combined with a dash, e.g. orlando-florida – Michael Smith Jun 16 '15 at 21:19
  • I just tested this out. This solution won't work. It does not guarantee uniqueness! There can be many cases where there is a restaurant with multiple locations in the same city. This would result in an error like such: IntegrityError... duplicate key value violates unique constraint ... DETAIL: Key (name_slug)=(pizza-place-test-orlando-fl) already exists. – Michael Smith Jun 16 '15 at 21:36
  • its up to you to find a better logic for your models, this solution answers your question on how to make the ```SlugField```, since you didn't provide any actual code logic, i abstracted the solution enough for you to implement on your own. – HassenPy Jun 16 '15 at 21:51
  • 1
    Ok, thank you for the guidance. I ended up using part of your "save logic" then following this post to create unique slugs: http://stackoverflow.com/questions/12486557/generating-unique-slug-in-django – Michael Smith Jun 16 '15 at 22:13