如何在 Django 中使用和创建信号?

在本示例中,您将学习如何在 django 中使用和创建信号。
您将学习如何在 django 中创建和使用信号。
我们将看一下如何在 django 中使用信号的示例。
本文将为您提供 django 自定义信号示例的简单示例。
让我们开始使用 django 中的自定义信号。

Django 信号用于对模型实例的修改执行任何操作。信号是帮助我们将事件与动作联系起来的实用程序。我们可以开发一个在信号调用时运行的函数。信号用于对数据库中特定条目的修改/创建执行一些操作。例如,一旦在数据库中创建了一个新的用户实例,就会想要创建一个配置文件实例。

有3种信号类型:
  • pre_save/post_save:此信号在方法 save() 之前/之后工作。
  • pre_delete/post_delete:此信号在删除模型实例(方法 delete())之前起作用,此信号被抛出。
  • pre_init/post_init:在实例化模型之前/之后抛出此信号(__init__() 方法)。

因此,如何使用 Signals ion Django:如果我们想在使用post_save信号创建用户后立即创建用户的个人资料,则基本上使用 Signals

在这里,我简单地逐步解释了如何在 django 中使用和创建信号的示例。

第 1 步:创建项目

在这一步中,我们将使用 django-admin 创建一个新的 django 项目。返回命令行界面并运行以下命令:

django-admin startproject example

第 2 步:创建应用程序

现在我们将创建一个名为core的应用程序来存储帖子名称列表。我们有意保持基本。使用Control+c停止本地服务器并使用startapp命令创建这个新应用程序。

python3 manage.py startapp core

第三步:更新setting.py

然后在我们的settings.py文件中更新INSTALLED_APPS以通知 Django 该应用程序。
settings.py

....
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'core',
]

第 4 步:创建模型

现在选择我们将要使用的模型 我们将调用我们的单个模型 Post ,它将只有两个字段:userimage。最后设置__str__以在管理界面中显示用户的用户名。 core/models.py

from django.db import models
from django.contrib.auth.models import User
from PIL import Image

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')

    def __str__(self):
        return f'{self.user.username} Profile'

好的,一切就绪。我们可以为此更改生成一个迁移文件,然后通过 migrate 将其集成到我们的数据库中。

python manage.py makemigrations
python manage.py migrate

第 5 步:创建表单

在这一步中,我们需要创建一个将被使用的表单。比如在 contrib.auth.forms 中添加一个 UserCreationForm,第二个表单是 UserUpdateForm,最后一个是 ProfileUpdateForm。另外,我们需要添加自定义样式。
core/forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']


class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email']


class ProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['image']

第 6 步:创建视图

在这一步中,我们需要配置我们的五个视图。注册页面将是 django 模板中带有 UserRegisterForm的注册模板。配置文件视图是使用 UserUpdateForm 和 ProfileUpdateForm 更新用户配置文件打开 core/views.py 文件并添加: core/views.py

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm


def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Your account has been created! You are now able to log in')
            return redirect('login')
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form': form})


@login_required
def profile(request):
    if request.method == 'POST':
        u_form = UserUpdateForm(request.POST, instance=request.user)
        p_form = ProfileUpdateForm(request.POST,
                                request.FILES,
                                instance=request.user.profile)
        if u_form.is_valid() and p_form.is_valid():
            u_form.save()
            p_form.save()
            messages.success(request, f'Your account has been updated!')
            return redirect('profile')

    else:
        u_form = UserUpdateForm(instance=request.user)
        p_form = ProfileUpdateForm(instance=request.user.profile)

    context = {
        'u_form': u_form,
        'p_form': p_form
    }

    return render(request, 'users/profile.html', context)

第 7 步:创建 signals.py 文件

在这一步中,我们需要配置一个signals.pycreate_profile方法是使用接收器方法配置文件是创建打开 core/views.py 文件并添加: core/signals.py

from django.db.models.signals import post_save, pre_delete
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
        instance.profile.save()

在这里,如果您是 Django 新手,您可能会对这段代码感到困惑,所以当保存 User 模型时,会触发一个名为create_profile的信号,该信号会创建一个带有指向实例的外键的 Profile 实例用户。另一种方法save_profile只是保存实例。

  • receiver 接收信号并做某事的功能。
  • sender:发送信号
  • created:检查模型是否已创建。
  • instance 创建的模型实例。
  • **kwargs:通配符关键字参数。

我们需要将信号文件与apps.py文件准备功能连接起来才能使用它们。core/apps.py

from django.apps import AppConfig

class UsersConfig(AppConfig):
    name = 'users'

    def ready(self):
        import users.signals

信号在这里存在。如果我们创建一个用户,那么他的个人资料就会自动创建。

您也可以在管理视图中检查它:

pre_save使用接收器方法:

pre_save方法是在调用 save 函数之前触发的,并且模型仅在成功执行pre_save方法后才保存

# code
from django.db.models.signals import post_save, pre_delete,pre_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile


@receiver(pre_save, sender=User)
def checker(sender, instance, **kwargs):
    if instance.id is None:
        pass
    else:
    current=instance
    previous=User.objects.get(id=instance.id)
    if previous.reaction!= current.reaction:
            #save method can be called

接下来,我们可以使用信号连接方法

如果您只使用post_save.connect(my_function),那么只要调用任何 save 方法,它就会被调用。

post_save.connect(my_function_post_save, sender=MyModel)
pre_save.connect(my_function, sender= UserTextMessage)

希望对您有用….

how-to-use-and-create-signals-in-django

发表评论

邮箱地址不会被公开。 必填项已用*标注