簡體   English   中英

django:signals不起作用pre_save()

[英]django :signals is not working pre_save()

我有用戶應用。

在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。

進一步,我建議更改為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

在用戶應用程序的__init__.py中,您必須設置在apps.py創建的應用程序配置

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM