gpt4 book ai didi

django - 如何让 grappelli 自动完成小部件代替 ModelMultipleChoiceField(在一对多方向上)工作?

转载 作者:行者123 更新时间:2023-12-04 21:18:25 26 4
gpt4 key购买 nike

使用 Django Grappelli 管理工具,我可以将 ForeignKey(多对一)字段配置为显示为自动完成小部件,而不是下拉字段,如下所示:

class MyModel(models.Model):
related = models.ForeignKey(RelatedModel, related_name='my_models')

class MyModelAdmin(admin.ModelAdmin):
raw_id_fields = ('related',)
autocomplete_lookup_fields = {
'fk': ['related'],
}

但是,我想做的是在另一个(一对多)方向(即在相关模型的管理员中定义自动完成小部件查找,以便我可以查找一个或多个 MyModel 对象)。现在,我只是在使用 ModelMultipleChoiceField:
class RelatedModelForm(forms.ModelForm):
class Meta:
model = RelatedModel
fields = ('my_models',)
my_models = forms.ModelMultipleChoiceField(queryset=MyModel.objects.all())

def __init__(self, *args, **kwargs):
super(SaleAdminForm, self).__init__(*args, **kwargs)
if self.instance:
self.fields['foods'].initial = self.instance.foods.all()

def save(self, *args, **kwargs):
instance = super(RelatedModelForm, self).save(commit=False)
self.fields['my_models'].initial.update(related=None)
self.cleaned_data['my_models'].update(related=instance)
return instance

class RelatedModelAdmin(admin.ModelAdmin):
model = RelatedModel
form = RelatedModelForm

但是,有太多 MyModel 实例无法很好地与该类型的小部件配合使用。最好为 MyModel 对象使用一个或多个自动完成查找小部件来代替 ModelMultipleChoiceField。

Grappelli 有一种简单的方法可以对 FK 关系和 m2m 关系进行自动完成查找,但有没有一种方法可以实现一对多关系?似乎这些自动完成功能与其他两种类型的关系一样有用,所以我猜想 Grappelli 也会在那里提供一种简单的方法,但我没有找到它......

最佳答案

我最终做的是将 ForeignKey 字段直接添加到 RelatedModel 类,以便我可以使用它来让 Grappelli 将自动完成功能放在页面上。该字段不用于存储任何内容,仅用于自动完成查找。因此,我的类(class)如下所示:

class MyModel(models.Model):
related = models.ForeignKey(RelatedModel, related_name='my_models')

class RelatedModel(models.Model):
# Used only for autocomplete lookups in the admin (Grappelli requires that a FK or m2m relationship exists in the model).
mockMyModel = models.ForeignKey(MyModel, verbose_name='Add a MyModel', related_name='for_mymodel_lookups')
# my_models - implied one-to-many field

class RelatedModelAdmin(admin.ModelAdmin):
model = RelatedModel
form = RelatedModelAdminForm

raw_id_fields = ('mockMyModel',)
autocomplete_lookup_fields = {
'fk': ['mockMyModel'],
}

class RelatedModelAdminForm(forms.ModelForm):
class Meta:
model = RelatedModel
fields = ('mockMyModel', 'my_models',)

# Note that you need to override __init__() and save() to get this field to work.
my_models = forms.ModelMultipleChoiceField(queryset=MyModel.objects.all(), required=False)

def __init__(self, *args, **kwargs):
super(RelatedModelAdminForm, self).__init__(*args, **kwargs)
if self.instance:
self.fields['my_models'].initial = self.instance.my_models.all()

def save(self, *args, **kwargs):
# TODO: Wrap reassignments into transaction
instance = super(RelatedModelAdminForm, self).save(commit=False)
self.fields['my_models'].initial.update(sale=None)
self.cleaned_data['my_models'].update(sale=instance)
return instance

以上在页面上呈现了一个自动完成小部件(用于模拟 FK 关系)和一个多选小部件(用于一对多关系)。然后我制作了一个 jquery 插件,从 View 中隐藏多选字段并劫持自动完成小部件以将用户在那里选择的每个值复制到多选字段中,在每次选择后清除自动完成。这有点像黑客......但它完成了工作。

关于django - 如何让 grappelli 自动完成小部件代替 ModelMultipleChoiceField(在一对多方向上)工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17473266/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com