2

I want this to fail:

MyModelWithSlug.objects.create(name='Foo', slug='abc . ü')

The string abc . ü is not a valid slug in django.

How to make above line fail?

guettli
  • 25,042
  • 81
  • 346
  • 663
  • 1
    Please leave a comment why this question should be closed or down-voted. Thank you. – guettli Feb 02 '17 at 13:55
  • Could you put your model definition in your question – iklinac Feb 02 '17 at 14:04
  • Similar questions [here](http://stackoverflow.com/questions/12945339/is-this-the-way-to-validate-django-model-fields/12945692#12945692) and [here](http://stackoverflow.com/questions/21939045/model-objects-create-equivalent-that-performs-a-full-clean/21939201#21939201). If you don't want to call `full_clean` manually, you could override the `save` and `create` methods manually, but this might lead to the model being validated twice, or unexpected validation errors causing 500 responses. – Alasdair Feb 02 '17 at 14:06
  • @iklinac I think the model definition is redundant. It's a model with a field called "slug", which is a SlugField. – guettli Feb 02 '17 at 21:40

1 Answers1

4

Read Alasdair's comment on OP

Django provides a hook called CLEAN to add custom validation but beware Django doesn't call it automatically on either save or create. So you have to override save() on model as well.(Thanks to @alasdair for correcting me.)

So the model becomes:

class MyModelWithSlug(models.Model):
    name = models.CharField(max_length=200, default="")
    slug = models.CharField(max_length=200, null=True, blank=True)

    def clean(self):
        # will raise an Validation Error even if unicode is present. refer validate_unicode_slug
        self.slug = validators.validate_slug(self.slug)

    def save(self):
        self.full_clean() # calls self.clean() as well cleans other fields
         return super(MyModelWithSlug, self).save(*args, **kwargs)

Or Even better:

class MyModelWithSlug(models.Model):
    name = models.CharField(max_length=200, default="")
    slug = models.SlugField(max_length=200, null=True, blank=True)

VALIDATE SLUG LINK

SLUG FIELD LINK

SomeTypeFoo
  • 886
  • 7
  • 16
  • This doesn't really answer the question. The slug field means that `instance = MyModelWithSlug(name='Foo', slug='abc . ü'); instance.full_clean()` will already trigger a validation error - there's no need for an extra `clean` method. The OP wants `MyModelWithSlug.objects.create(name='Foo', slug='abc . ü')` to trigger the same validation error. – Alasdair Feb 02 '17 at 14:30
  • Yes if you hook up the clean method..you dont really need to call `instance.full_clean()`..django calls its model's `clean` method during `MyModelWithSlug.objects.create(name='Foo', slug='abc . ü')` as well. – SomeTypeFoo Feb 03 '17 at 05:30
  • No, Django does not call `clean` during `create`. – Alasdair Feb 03 '17 at 08:37
  • @Alasdair Thanks for correcting me. Seems like none of the clean functions are called automatically. Edited answer accordingly. – SomeTypeFoo Feb 03 '17 at 10:33
  • It would be better to call [`full_clean`](https://docs.djangoproject.com/en/1.10/ref/models/instances/#validating-objects) instead of `clean`. The `full_clean` method validates the fields and calls `clean`. And since `full_clean` validates the fields, there is no need to call `validate_slug` manually in `clean`. – Alasdair Feb 03 '17 at 10:47
  • But the model there is a CharField. that is why the clean method. Corrected the answer again. Thanks. – SomeTypeFoo Feb 03 '17 at 10:55
  • Sorry, didn't spot that you had used a `CharField` instead of a `SlugField` in your answer. It would be clearer if @guettli had posted an example model when asked rather than saying it's redundant. – Alasdair Feb 03 '17 at 11:03