Skip to main content
 首页 » 编程设计

python之Django:管理界面中的 OneToOne 下拉列表和唯一关联

2024年09月07日33zfyouxi

引用Django - one-to-one modelAdmin我仍在寻找 Django 管理界面和我的 OneToOne 关系问题的解决方案。

我有以下模型,它使用附加属性 is_thing_staff 扩展了标准用户模型:

class ThingStaff(models.Model): 
    """ Extends the django user model by a separate model relationship which holds additional user 
    attributes 
    """ 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    # by default a new user is not a staff member which take care of the thing administration 
    is_thing_staff = models.BooleanField(default=False) 
 
    def __str__(self): 
        return u"{}".format(self.user.username) 
 
    class Meta: 
        verbose_name = "Thing Staff" 
        verbose_name_plural = "Thing Staff" 

如果我在 Django 管理界面中创建一个新的 ThingStaff 对象,我可以选择所有用户,即使已经存在一个用户的关系。保存与用户具有重复关联的新对象会导致错误,即已存在与该用户关联的 ThingStaff 对象。到目前为止,这或多或少没问题。

但是,如果可能的选择会导致下一步出错,为什么还要显示可能的选择呢?所以我通过

排除了他们
from django import forms 
from django.contrib import admin 
from .models import ThingStaff 
 
class ThingStaffForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
        super(ThingStaffForm, self).__init__(*args, **kwargs) 
        self.fields['user'].queryset = User.objects.exclude( 
           id__in=ThingStaff.objects.values_list('user_id', flat=True) 
        ) 
 
@admin.register(ThingStaff) 
class ThingStaffAdmin(admin.ModelAdmin): 
    form = ThingStaffForm 

到目前为止一切顺利:在创建新的 ThingStaff 对象期间,已经关联的用户不会显示在下拉列表中。

但如果我想更改现有关联,相关用户也不会出现在下拉列表中,这使得无法重置 is_thing_staff 标志。

所以我的问题是:如何在 django 管理界面中为更改 View 再次启用该特定用户?

请您参考如下方法:

Django 的 ModelForm 区分添加和更改 View (每个 View 都有自己的方法)。这意味着您可以覆盖它:

class ThingStaffAdmin(ModelAdmin): 
     def add_view(self, *args, **kwargs): 
         self.form = ThingStaffAddForm 
         return super().add_view(*args, **kwargs) 
 
     def change_view(self, *args, **kwargs): 
         self.form = ThingStaffChangeForm 
         return super().change_view(*args, **kwargs) 

文档中的更多内容:

https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.change_view