简体   繁体   English

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

[英]How to set default value for a ManyToManyField in Django

edit- updated models.py models.py:编辑更新的 models.py models.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()
                 

My query/requirement: Employee and Department are linked by M2M.我的查询/要求:员工和部门由 M2M 链接。 I set blank=True to overcome the form validation of no department being chosen.我设置 blank=True 来克服没有选择部门的表单验证。 (null=True doesn't seem to be working with M2M) (null=True 似乎不适用于 M2M)

Let's say,比方说,

scenario 1: while creating a new Emp, if there is no department provided then it should set to RP(Resource pool) by default.场景一:新建Emp时,如果没有提供department,默认设置为RP(Resource pool)。

scenario 2: An existing Emp is from the HR department;场景二:现有Emp来自HR部门; assuming for some reason the HR dept is being deleted or Emp is being kicked out, now that Emp has no department linked to it, it should move to RP(Resource pool) by default!!假设由于某种原因 HR 部门被删除或 Emp 被踢出,现在 Emp 没有部门链接到它,它应该默认移动到 RP(资源池)!!

How to arrange the default department- RP in Django such that both the scenarios are passing??如何在 Django 中安排默认部门- RP,以便两种情况都通过?

Thanks in advance:)提前致谢:)

Dueces决斗

As suggested here The right way to set the default value of a ManyToMany field in django , you have a few options.正如这里所建议的 The right way to set the default value of a ManyToMany field in django ,你有几个选择。

Here is how to do so by overriding the save method:以下是如何通过覆盖保存方法来做到这一点:

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)

Here is how to do so using a post_save receiver:以下是使用 post_save 接收器的方法:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM