django:signals不起作用pre_save()

时间:2018-12-04 15:33:48

标签: python django

我有用户应用。

在signals.py中,我有

from django.db.models.signals import pre_save
from user.models import User
from django.dispatch import receiver
import random
import string

@receiver(pre_save,sender=User)
def create_hash_for_user(sender,instance,**kwargs):
    allowed_chars = ''.join((string.ascii_letters, string.digits))
    unique_id = ''.join(random.choice(allowed_chars) for _ in range(32))
    print("Request finished!")
    instance.user_hash = unique_id
    instance.save()

在apps.py

from django.apps import AppConfig


class UserConfig(AppConfig):
    name = 'user'

    def ready(self):
        import user.signals

在models.py中 我已经扩展了abstractbaseuser

from django.db import models
from django.shortcuts import render
from django.core.exceptions import ValidationError
from django.contrib.auth.models import (
        AbstractBaseUser,
        BaseUserManager
    )

from .utils import file_size

class MyUserManager(BaseUserManager):
    def create_user(self, username,email,password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
            username=username
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self,username,email,password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(
            username=username,
            email=email,
            password=password,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):
    username=models.CharField(max_length=200,blank=True,null=True)
    first_name = models.CharField(max_length=100,blank=True,null=True)
    last_name = models.CharField(max_length=100, blank=True, null=True)
    email = models.EmailField(unique=True)
    image = models.ImageField(upload_to='images',blank=True,validators=[file_size])
    date_joined = models.DateTimeField(auto_now=False,auto_now_add=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    user_hash = models.CharField(max_length=512,blank=True,null=True)

    USERNAME_FIELD='email'

    objects = MyUserManager()

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.is_admin

但是信号函数没有被调用,请求完成!不会打印,也不会创建user_hash。

2 个答案:

答案 0 :(得分:1)

Furthurmore,我建议更改为post_save,而不是pre_save

在您的代码中,每个用户为用户的每个save()方法创建一个自己的user_hash。我想你不是故意的。

user_hash仅在创建后立即创建。因此,您可以将post_savecreated命令一起使用。像这样

@receiver(post_save, sender=User)
def create_hash_post_save(sender, instance, created, **kwargs):
    if created:
        allowed_chars = ''.join((string.ascii_letters, string.digits))
        unique_id = ''.join(random.choice(allowed_chars) for _ in range(32))
        print("Request finished!")
        instance.user_hash = unique_id
        instance.save()

或者,在添加user_hash之前,应检查实例是否具有pk。像这样

@receiver(pre_save,sender=User)
def create_hash_for_user(sender,instance,**kwargs):
    if not instance.pk:
        allowed_chars = ''.join((string.ascii_letters, string.digits))
        unique_id = ''.join(random.choice(allowed_chars) for _ in range(32))
        print("Request finished!")
        instance.user_hash = unique_id

答案 1 :(得分:1)

在您的__init__.py用户应用程序中,您必须设置在apps.py中创建的应用程序配置

# __init__.py
default_app_config = 'user.apps.UserConfig'