How can I give `def formfield_for_manytomany` an id of editable object

前端 未结 2 913
日久生厌
日久生厌 2021-02-10 07:34
class Report(models.Model):
    precursor = models.ManyToManyField(Precursor)

class ReportAdmin(admin.ModelAdmin):
    def formfield_for_manytomany(self, db_field, requ         


        
相关标签:
2条回答
  • 2021-02-10 08:05

    Assuming you're after the Report instance being edited by the ReportAdmin, try this:

    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)
    
    0 讨论(0)
  • 2021-02-10 08:15

    The problem with DrMeer's otherwise excellent answer is that the object will be cached inside the ModelAdmin instance and its lifetime will extend until next get_object() call. However, get_object() is not called when adding a new report, so the wrong, previous report obj will be present when you add a new report after changing an existing report.

    A safer approach is to cache the report object in the request, so it has request scope:

    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)
    
    0 讨论(0)
提交回复
热议问题