Django post_save hook导致syncdb出错

时间:2014-03-24 18:15:31

标签: python django django-syncdb

我有一个与User(django.contrib.auth.models.User)模型具有OneToOne关系的自定义模型;

class Profile(models.Model):
    user = models.OneToOneField(User)

我希望每次创建用户时都创建一个新的配置文件。所以我添加了一个信号;

@receiver(post_save, sender=User)
def _setup_user(sender, **kwargs):
    """
    Create a new profile instance for each user
    """
    created = kwargs.get('created', False)
    user = kwargs.get('instance', False)
    if created and user:
        profile = Profile(user=kwargs['instance'])
        profile.save()

所有这一切都很好,但是在创建管理员用户时syncdb会抛出错误,因为尚未创建配置文件表(我使用南来管理迁移)。

我怎样才能解决这个问题?

修改

因此,省略创建超级用户的工作;

$ ./manage.py syncdb --noinput
$ ./manage.py migrate
$ ./manage.py createsuperuser

2 个答案:

答案 0 :(得分:1)

首先运行syncdb并拒绝制作superuser。然后在创建数据库运行manage.py createsuperuser

之后

Here's 1.6的文档

如果您有任何问题请告诉我,但如果唯一的问题是不首先创建数据库,那么这应该可行。

希望有所帮助

干杯

答案 1 :(得分:1)

您可以尝试这样的事情:

from django.db import DatabaseError, transaction

@receiver(post_save, sender=User)
@transaction.commit_manually
def _setup_user(sender, **kwargs):
    """
    Create a new profile instance for each user
    """
    created = kwargs.get('created', False)
    user = kwargs.get('instance', False)
    if created and user:
        try:
            profile = Profile(user=kwargs['instance'])
            profile.save()
        except DatabaseError:
            transaction.rollback()
        else:
            transaction.commit()

根据您的数据库后端,您可能不需要手动事务管理,但对于psycopg2,它是必要的,否则您将获得" current transaction is aborted"错误。

如果你采用这种方法,那么你需要在运行syncdb后手动为超级用户创建一个配置文件,所以在这种特定情况下我认为TheSpurg's answer更简单。仍然值得知道如何从DataBaseError中恢复,所以无论如何我都要发布这个答案。