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)
How can I give def formfield_for_manytomany an id of editable object?
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)
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With