我如何给`def formfield_for_manytomany`一个可编辑对象的id

mak*_*mov 4 django django-models django-forms django-admin

class Report(models.Model):
    precursor = models.ManyToManyField(Precursor)

class ReportAdmin(admin.ModelAdmin):
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        ops_area = Report.objects.get(id=???????).ops_area
        print id
        print ops_area
        if db_field.name == "r_precursor":
            kwargs["queryset"] = Precursor.objects.filter(ops_area=ops_area)
            print kwargs
        return super(ReportAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

如何给出def formfield_for_manytomany可编辑对象的id?

DrM*_*ers 14

假设您Report正在编辑实例ReportAdmin,请尝试以下操作:

class ReportAdmin(admin.ModelAdmin):
    def get_object(self, request, object_id):
        # Hook obj for use in formfield_for_manytomany
        self.obj = super(ReportAdmin, self).get_object(request, object_id)
        print "Got object:", self.obj
        return self.obj

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "r_precursor" and getattr(self, 'obj', None):
            kwargs["queryset"] = Precursor.objects.filter(
                ops_area=self.obj.ops_area)
        return super(ReportAdmin, self).formfield_for_manytomany(
            db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

  • 这取决于你使用它的位置(也许是Django的版本).您也可以在`get_form`和`get_formset`方法中尝试.有关适用于内联的版本,请参阅我的[预编辑帖子](http://stackoverflow.com/posts/5216214/revisions). (3认同)
  • 'ReportAdmin' 对象没有属性 'obj' (2认同)

mrt*_*rts 8

DrMeer 的其他优秀答案的问题是该对象将被缓存在实例内ModelAdmin,并且其生命周期将延长到下一次get_object()调用。但是,get_object()在添加新报告时不会调用,因此obj当您在更改现有报告后添加新报告时,将出现错误的先前报告。

更安全的方法是将报表对象缓存在request中,因此它具有 request 作用域:

class ReportAdmin(admin.ModelAdmin):
    def get_object(self, request, object_id, from_field=None):
        obj = super().get_object(request, object_id, from_field=from_field)
        # Cache object for use in formfield_for_manytomany
        request.report_obj = obj
        return obj

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "r_precursor" and hasattr(request, 'report_obj'):
            kwargs["queryset"] = Precursor.objects.filter(
                ops_area=request.report_obj.ops_area)
        return super(ReportAdmin, self).formfield_for_manytomany(
            db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)