【问题标题】:Use field value in limit_choices_to in Django在 Django 中使用 limit_choices_to 中的字段值
【发布时间】:2015-03-06 14:38:26
【问题描述】:

我有两个型号 ProjectGroup。我的小组属于一个特定的项目。我的小组有project = ForeignKey(Project)parent = ForeignKey('self') 字段。

我可以使用limit_choices_to 来确保外键parent 中的选项仅由同一项目内的组组成吗?

我正在考虑类似的事情

def limit_choices_to(self):
    return {'project': self.project}

【问题讨论】:

    标签: django django-models django-mptt


    【解决方案1】:

    这在模型级别是不可能的,但您可以在表单的构造函数中更改该字段的查询集。

    class GroupForm(forms.ModelForm):
    
        def __init__(self, *args, **kwargs):
            super(GroupForm, self).__init__(*args, **kwargs)
            if self.instance.project:
                self.fields['parent'].queryset = Group.objects.filter(
                                                    project=self.instance.project)
    

    更新:要在管理员中执行此操作,您必须设置ModelAdminform 属性:

    class GroupAdmin(admin.ModelAdmin):
        form = GroupForm
    

    【讨论】:

    • 谢谢!但是我怎样才能在管理部分完成同样的结果呢?
    • 我认为,这应该可以在模型级别使用 limit_choices_to={'project__id': Value('id')} 进行,但我收到了类似 psycopg2.errors.InvalidCursorName: cursor "_django_curs_140361007625984_sync_1" does not exist 的错误
    【解决方案2】:

    对于管理部分,我发现了一种很老套的方法。我的示例是使用 admin.StackedInline,但几乎可以肯定它适用于普通的 ModelAdmin。我把它留在这里,以防有人喜欢这个解决方案:

    class ProfessionalInline(admin.StackedInline):
    model = Professional
    
    fieldsets = [
        ('Research information', {
            'fields': ('team', 'projects')
        }),
        ('Profile information', {
            'fields': ('age', 'gender', 'receive_emails')
        })]
    
    def get_parent_object_from_request(self, request):
        """
        Returns the parent object from the request or None.
    
        Note that this only works for Inlines, because the `parent_model`
        is not available in the regular admin.ModelAdmin as an attribute.
        """
        resolved = resolve(request.path_info)
        if resolved.kwargs:
            return self.parent_model.objects.get(pk=resolved.kwargs['object_id'])
        return None
    
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        '''Extremely hacky'''
        account = self.get_parent_object_from_request(request)
        if db_field.name == 'projects':
            kwargs['queryset'] = Project.objects.filter(team=account.professional.team)
        return super().formfield_for_manytomany(db_field, request, **kwargs)
    

    【讨论】:

      猜你喜欢
      • 2013-08-13
      • 1970-01-01
      • 2015-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多