简体   繁体   English

如何在Django的同一表中阻止外键的相同对象引用?

[英]How to block same object reference for Foreign key in same table in Django?

I have a Model which has a self foreign key. 我有一个具有自我外键的模型。

models.py models.py

class Employee(AbstractUser):
    manager = models.ForeignKey('self', on_delete=models.SET_NULL, related_name=_('manger'), null=True)

Now when i add this Model to admin site and try to update an employee users's can set themself as their own manager. 现在,当我将此模型添加到管理站点并尝试更新员工时,用户可以将他们自己设置为自己的经理。 So if i am trying to update employee ID #1, I dont want employee ID #1 to be displayed in the managers dropdown. 因此,如果我要更新员工ID#1,我不希望在管理器下拉列表中显示员工ID#1。

Additional Question 附加问题

I know that i can add clean method that validates this condition in my Update form, however i do not know how to get the current object ID to check against manager ID. 我知道我可以在“更新”表单中添加验证此条件的干净方法,但是我不知道如何获取当前对象ID以对照管理器ID进行检查。

forms.py forms.py

class EmployeeChangeForm(UserChangeForm):

   class Meta:
        model = Employee
        fields = '__all__'

   def clean_manager(self):
        # An Employee Cannot have himself assigned as a manager

        eID = ??  # how do i get the id of Current Employee here ?
        mgr = self.cleaned_data["manager"]
        if eID == mgr:
           raise forms.ValidationError("Employee and Manger should be diffrent !!")
        return mgr

The above approach will not allow the current user to block employee from setting himself as setting as his manager however, the employee will still show in the dropdown of the manager field. 上述方法将不允许当前用户阻止员工将自己设置为经理,但是该员工仍将显示在经理字段的下拉列表中。 I would prefer if the current employee does not show in the dropdown at all. 我希望当前的员工完全不显示在下拉菜单中。

Is there a way to do that ? 有没有办法做到这一点 ?

Update: 更新:

I just learned about ForeignKey.limit_choices_to which limits the choices to a particuler set from related table. 我刚刚了解了ForeignKey.limit_choices_to ,该方法将相关表的选择限制为一个特定的集。 However, again i do not know how will i pass the current user id to the set. 但是,再次,我不知道如何将当前用户ID传递给集合。

for example: 例如:

models.py models.py

from django.db.models import Q

class Employee(AbstractUser):
    manager = models.ForeignKey(
      'self',
      on_delete=models.SET_NULL,
      related_name=_('manger'),
      null=True,
      limit_choices_to=~Q(id=3),
)

the above code limits my manager choices to all manager's except 3. but i dont know how to make this valie dynamic. 上面的代码将我的经理的选择限制为除3之外的所有经理。但是我不知道如何使这种优势成为动态。

I cant do limit_choices_to=~Q(id=self.pk) or limit_choices_to=~Q(id=self.id) 我不能做limit_choices_to=~Q(id=self.pk)limit_choices_to=~Q(id=self.id)

Please help 请帮忙

Try this: 尝试这个:

class EmployeeChangeForm(UserChangeForm):

    class Meta:
        model = Employee
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance.pk:
            self.fields['manager'].queryset = Employee.objects.exclude(
                pk=self.instance.pk,
            )

Don't forget to use the form in your ModelAdmin by adding form = EmployeeChangeForm . 不要忘记通过添加form = EmployeeChangeFormModelAdmin使用该表单。

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

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