Python 如何为Django中的ManyToManyField设置默认值

Python 如何为Django中的ManyToManyField设置默认值,python,django,django-models,default-value,manytomanyfield,Python,Django,Django Models,Default Value,Manytomanyfield,编辑-更新的models.py 型号。py: from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class Department(models.Model): departmentName = models.CharField(max_length=100) def __str__(self):

编辑-更新的models.py 型号。py:

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

class Department(models.Model):
    departmentName = models.CharField(max_length=100)

    def __str__(self):
        return self.departmentName

class Designation(models.Model):
    designationName = models.CharField(max_length=100, null=True)

    def __str__(self):
        return self.designationName
 
class Employee(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True, blank=False)
    department = models.ManyToManyField(Department, blank=True)
    designation = models.ForeignKey(Designation, null=True, on_delete=models.SET_NULL)

    def __str__(self):
        return self.name
    
    def departments(self):
        return ",".join([d.departmentName for d in self.department.all()])

#Using post receiver signal as suggested by @Daniel in answer and comments

@receiver(post_save, sender=Employee, dispatch_uid='set_department')
def SetDefaultDeparment(**kwargs):

    employee = kwargs['instance']
       
    if not employee.department.all(): 

        resource_pool = Department.objects.get(departmentName="RP")

        employee.department.add(resource_pool)
        employee.save()
                 
我的查询/需求:员工和部门通过M2M链接。我设置blank=True以克服没有选择部门的表单验证。(null=True似乎不适用于M2M)

比方说

场景1:创建新Emp时,如果没有提供部门,则默认情况下应将其设置为RP(资源池)

场景2:现有Emp来自人力资源部;假设由于某种原因,人力资源部门被删除或Emp被踢出,现在Emp没有与之链接的部门,默认情况下它应该移动到RP(资源池)

如何在Django中安排默认的department-RP,以使两个场景都通过

提前感谢:)

会费

正如这里所建议的,您有几个选择

下面是如何通过重写save方法来完成此操作:

class Employee(models.Model):

    ...
    
    def save(self): 

        # set department if field is empty:        
        if not self.department.all(): 

            # get the resource pool department:
            resource_pool = Department.objects.get(name='Resource Pool')

            # add to instance:
            self.department.add(resource_pool)
        
        super(Employee, self).save(*args, **kwargs)
以下是如何使用post_保存接收器执行此操作:

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

# this decorator will execute the function after an Employee is saved:
@receiver(post_save, sender=Employee, dispatch_uid='set_department')
def SetDefaultDeparment(**kwargs):
    
    ''' sets a default department for an Employee where needed '''
    
    # unpack kwargs:
    employee = kwargs['instance']

    # set department if field is empty:        
    if not employee.department.all(): 

         # get the resource pool department:
         resource_pool = Department.objects.get(name='Resource Pool')

         # add to instance:
         employee.department.add(resource_pool)
         employee.save()

异常值:“”需要为字段“id”设置一个值,才能使用此多对多关系。这是一个很好的问题—新员工会遇到这种情况,因为只有在保存新员工实例后(而不是之前)才会创建id,因此会出现错误。我们可以使用post_save receiver在这种情况下(以及所有情况下)添加默认部门-查看我的更新答案。嘿@Daniel,我尝试了更新。现在没有例外,但不幸的是,该部门仍然没有得到增加!(因为没有创建新的M2M关系)调试时发现-“无法通过员工实例访问经理”。在save()之前添加了此行-print(employee.department),它将打印employee\u app.department.none您可以共享您编辑的代码吗?您是否使用post save接收器?对于没有任何部门的员工,它应显示为空查询集,并像
False
一样工作-对于至少有一个部门的员工,它不应是空查询集,并像
True