代码之家  ›  专栏  ›  技术社区  ›  Ekaterina Premudraya

Django和模型中的信号post_保存

  •  1
  • Ekaterina Premudraya  · 技术社区  · 7 年前

    我有信号功能:

    @receiver(post_save, sender=Task)
    def my_handler():
        executor = User.objects.filter(user_type='Executer')
        executor.balance += Task.money
        executor.save()
    

    我的功能应该在添加任务后向执行者添加资金。但它会产生如下错误:

    Internal Server Error: /api/v1/tasks/
    Traceback (most recent call last):
      ...
      File "/home/k/pro/freelance-django/free/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1853, in get_prep_value
        return int(value)
    ValueError: invalid literal for int() with base 10: 'Executer'
    [20/Sep/2017 14:00:30] "POST /api/v1/tasks/ HTTP/1.1" 500 188088
    

    用户类

       from __future__ import unicode_literals
    
    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    
    class User(AbstractUser):
        CUSTOMER = 1
        EXECUTER = 2
    
        USER_TYPES = (
            (CUSTOMER, 'Customer'),
            (EXECUTER, 'Executer'),
        )
    
        user_type = models.IntegerField(choices=USER_TYPES, default=EXECUTER, verbose_name='Тип пользователя')
        balance = models.DecimalField(decimal_places=2, max_digits=7, default=0, verbose_name='Баланс')
    
    
        def __str__(self):
            return self.username
    

    来自任务。型号为:

    class Task(models.Model):
        title = models.CharField(max_length=255, verbose_name='Заголовок')
        description = models.CharField(max_length=255, verbose_name='Описание')
        money = models.DecimalField(max_digits=7, decimal_places=2, default=0, verbose_name='Цена')
        assignee = models.ForeignKey('users.User', related_name='assignee', null=True, verbose_name='Исполнитель')
        created_by = models.ForeignKey('users.User', related_name='created_by', verbose_name='Кем был создан')
    

    我该怎么做?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Thaian    7 年前

    你没有一个 但是 物体 update() . 最好的选择是使用F表达式,因为它在DB上执行,因此具有良好的性能:

    from django.db.models import F    
    
    @receiver(post_save, sender=Task)
    def my_handler(sender, instance, **kwargs):
        User.objects.filter(user_type=User.EXECUTER).update(balance=F('balance') + instance.money)
    

    这将更新用户类型为Executer的所有记录,并在一个查询中更新它们的余额。

    Django docs update

    F expressions

    你的 user_type

    class User(AbstractUser):
        CUSTOMER = 1
        EXECUTER = 2
    
        USER_TYPES = (
            (CUSTOMER, 'Customer'),
            (EXECUTER, 'Executer'),
        )
    
        user_type = models.IntegerField(choices=USER_TYPES, default=EXECUTER, verbose_name='Тип пользователя')
        balance = models.DecimalField(decimal_places=2, max_digits=7, default=0, verbose_name='Баланс')