首页 > 解决方案 > 用户注册后 Django 执行自定义代码

问题描述

users在 Django 项目中有一个应用程序(版本2.1和 python 3.6)。用户注册后(无论是前端还是在理想情况下添加到管理仪表板时),我想在另一个表中插入数据。我知道如何插入数据,但在成功注册后我不知道如何插入数据。

理想的答案只会告诉我如何print('hello')在用户创建帐户后立即执行类似操作。

# users/admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin

from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ['email', 'username',]

admin.site.register(CustomUser, CustomUserAdmin)

# users/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm):
        model = CustomUser
        fields = ('username', 'email')

class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = ('username', 'email')

# users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    # add additional fields in here
    credit = models.IntegerField(default=200) # editable=False
    def __str__(self):
        return self.email

# users/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('signup/', views.SignUp.as_view(), name='signup'),
]

# users/views.py
from django.urls import reverse_lazy
from django.views import generic

from .forms import CustomUserCreationForm

class SignUp(generic.CreateView):
    form_class = CustomUserCreationForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

标签: djangodjango-models

解决方案


使用保存后信号

https://docs.djangoproject.com/en/2.1/ref/signals/

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def say_hello(sender, instance, **kwargs):
     if instate._state.adding:
        print('hello')

Signal 比视图上的方法更好,因为用户可以通过视图以外的其他方式创建,例如,通过 shell、管理命令、迁移、不同的视图等。

请注意_state不是“私有的”,所以不要对使用它感到难过,它只是这样命名以避免与字段名称冲突。

检查 _state 而不是更常见的检查 instance.pk,因为当主键是自然键而不是 AutoField 时,总是存在 instance.pk


推荐阅读