Django model.save() not working with loaddata

I have a model which is overriding save() to slugify a field:

class MyModel(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(MyModel, self).save(*args, **kwargs)

When I run load data to load a fixture, this save() does not appear to be called because the slug field is empty in the database. Am I missing something?

I can get it to work by a pre_save hook signal, but this is a bit of a hack and it would be nice to get save() working.

def mymodel_pre_save(sender, **kwargs):
    instance = kwargs['instance']
    instance.slug = slugify(instance.name)

pre_save.connect(mymodel_pre_save, sender=MyModel)

Thanks in advance.


No you're not. save() is NOT called by loaddata, by design (its way more resource intensive, I suppose). Sorry.

EDIT: According to the docs, pre-save is not called either (even though apparently it is?).

Data is saved to the database as-is, according to https://docs.djangoproject.com/en/dev/ref/django-admin/#what-sa-fixture


I'm doing something similar now - I need a second model to have a parallel entry for each of the first model in the fixture. The second model can be enabled/disabled, and has to retain that value across loaddata calls. Unfortunately, having a field with a default value (and leaving that field out of the fixture) doesn't seem to work - it gets reset to the default value when the fixture is loaded (The two models could have been combined otherwise).

So I'm on Django 1.4, and this is what I've found so far:

  • You're correct that save() is not called. There's a special DeserializedObject that does the insertion, by calling save_base() on the Model class - overriding save_base() on your model won't do anything since it's bypassed anyway.
  • @Dave is also correct: the current docs still say the pre-save signal is not called, but it is. It's behind a condition: if origin and not meta.auto_created
  • origin is the class for the model being saved, so I don't see why it would ever be falsy.
  • meta.auto_created has been False so far with everything I've tried, so I'm not yet sure what it's for. Looking at the Options object, it seems to have something to do with abstract models.
  • So yes, the pre_save signal is indeed being sent.
  • Further down, there's a post_save signal behind the same condition that is also being sent.
  • Using the post_save signal works. My models are more complex, including a ManyToMany on the "Enabled" model, but basically I'm using it like this:

    from django.db.models.signals import post_save
    
    class Info(models.Model):
       name = models.TextField()
    
    class Enabled(models.Model):
       info = models.ForeignKey(Info)
    
    def create_enabled(sender, instance, *args, **kwards):
       if Info == sender:
          Enabled.objects.get_or_create(id=instance.id, info=instance)
    
    post_save.connect(create_enabled)
    

    And of course, initial_data.json only defines instances of Info .

    链接地址: http://www.djcxy.com/p/9144.html

    上一篇: 有没有办法禁用Access 2007的代码编辑器CTRL + Y快捷键?

    下一篇: Django model.save()不适用于loaddata