prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Improve annotation admin pages
  The graders have asked me to delete all annotations for one user for a specific image. There is currently no easy way to do this in the admin pages. I will need to find a way to make this possible. Probably by adding certain search_fields or list_filters.
  
  Also, I have noticed that some admin pages take extremely long to load. For example the change page for a polygon annotation set. I think this happens because it has to load a lot of data which it does not do efficiently and because it makes all inline model fields are editable by default. It will most likely never happen that we need to change this data manually so those fields can all be set to read_only. It might also be better to just have some statistics there about the number of inline models and not show the actual inline models at all.
  Example loading time for an admin page:
  ![image](https://user-images.githubusercontent.com/2001094/73462398-08bf9380-437c-11ea-9116-a6170c114176.png)
  
  
  </issue>
  <code>
  [start of app/grandchallenge/annotations/admin.py]
  1 from django.contrib import admin
  2 
  3 from grandchallenge.annotations.models import (
  4     BooleanClassificationAnnotation,
  5     ETDRSGridAnnotation,
  6     LandmarkAnnotationSet,
  7     MeasurementAnnotation,
  8     PolygonAnnotationSet,
  9     SingleLandmarkAnnotation,
  10     SinglePolygonAnnotation,
  11 )
  12 
  13 
  14 class BooleanClassificationAnnotationAdmin(admin.ModelAdmin):
  15     search_fields = ("grader__username", "name", "created")
  16     list_filter = ("created", "value", "name")
  17 
  18 
  19 class SinglePolygonAnnotationInline(admin.StackedInline):
  20     model = SinglePolygonAnnotation
  21     extra = 0
  22 
  23 
  24 class PolygonAnnotationSetAdmin(admin.ModelAdmin):
  25     search_fields = ("grader__username", "created", "name")
  26     list_filter = ("created", "grader__username", "name")
  27     inlines = [SinglePolygonAnnotationInline]
  28 
  29 
  30 class SingleLandmarkAnnotationInline(admin.StackedInline):
  31     model = SingleLandmarkAnnotation
  32     extra = 0
  33 
  34 
  35 class LandmarkAnnotationSetAdmin(admin.ModelAdmin):
  36     search_fields = ("grader__username", "created")
  37     list_filter = ("created", "grader__username")
  38     inlines = [SingleLandmarkAnnotationInline]
  39 
  40 
  41 admin.site.register(ETDRSGridAnnotation)
  42 admin.site.register(MeasurementAnnotation)
  43 admin.site.register(
  44     BooleanClassificationAnnotation, BooleanClassificationAnnotationAdmin
  45 )
  46 admin.site.register(PolygonAnnotationSet, PolygonAnnotationSetAdmin)
  47 admin.site.register(SinglePolygonAnnotation)
  48 admin.site.register(LandmarkAnnotationSet, LandmarkAnnotationSetAdmin)
  49 admin.site.register(SingleLandmarkAnnotation)
  50
  [end of app/grandchallenge/annotations/admin.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/app/grandchallenge/annotations/admin.py b/app/grandchallenge/annotations/admin.py
  --- a/app/grandchallenge/annotations/admin.py
  +++ b/app/grandchallenge/annotations/admin.py
  @@ -19,23 +19,33 @@
   class SinglePolygonAnnotationInline(admin.StackedInline):
       model = SinglePolygonAnnotation
       extra = 0
  +    readonly_fields = (
  +        "annotation_set",
  +        "value",
  +        "x_axis_orientation",
  +        "y_axis_orientation",
  +        "z",
  +    )
   
   
   class PolygonAnnotationSetAdmin(admin.ModelAdmin):
  -    search_fields = ("grader__username", "created", "name")
  +    search_fields = ("grader__username", "created", "name", "image__name")
       list_filter = ("created", "grader__username", "name")
       inlines = [SinglePolygonAnnotationInline]
  +    readonly_fields = ("grader", "image", "name", "created")
   
   
   class SingleLandmarkAnnotationInline(admin.StackedInline):
       model = SingleLandmarkAnnotation
       extra = 0
  +    readonly_fields = ("image", "landmarks")
   
   
   class LandmarkAnnotationSetAdmin(admin.ModelAdmin):
       search_fields = ("grader__username", "created")
       list_filter = ("created", "grader__username")
       inlines = [SingleLandmarkAnnotationInline]
  +    readonly_fields = ("grader", "created")
   
   
   admin.site.register(ETDRSGridAnnotation)
  
verification_info: {"golden_diff": "diff --git a/app/grandchallenge/annotations/admin.py b/app/grandchallenge/annotations/admin.py\n--- a/app/grandchallenge/annotations/admin.py\n+++ b/app/grandchallenge/annotations/admin.py\n@@ -19,23 +19,33 @@\n class SinglePolygonAnnotationInline(admin.StackedInline):\n     model = SinglePolygonAnnotation\n     extra = 0\n+    readonly_fields = (\n+        \"annotation_set\",\n+        \"value\",\n+        \"x_axis_orientation\",\n+        \"y_axis_orientation\",\n+        \"z\",\n+    )\n \n \n class PolygonAnnotationSetAdmin(admin.ModelAdmin):\n-    search_fields = (\"grader__username\", \"created\", \"name\")\n+    search_fields = (\"grader__username\", \"created\", \"name\", \"image__name\")\n     list_filter = (\"created\", \"grader__username\", \"name\")\n     inlines = [SinglePolygonAnnotationInline]\n+    readonly_fields = (\"grader\", \"image\", \"name\", \"created\")\n \n \n class SingleLandmarkAnnotationInline(admin.StackedInline):\n     model = SingleLandmarkAnnotation\n     extra = 0\n+    readonly_fields = (\"image\", \"landmarks\")\n \n \n class LandmarkAnnotationSetAdmin(admin.ModelAdmin):\n     search_fields = (\"grader__username\", \"created\")\n     list_filter = (\"created\", \"grader__username\")\n     inlines = [SingleLandmarkAnnotationInline]\n+    readonly_fields = (\"grader\", \"created\")\n \n \n admin.site.register(ETDRSGridAnnotation)\n", "issue": "Improve annotation admin pages\nThe graders have asked me to delete all annotations for one user for a specific image. There is currently no easy way to do this in the admin pages. I will need to find a way to make this possible. Probably by adding certain search_fields or list_filters.\r\n\r\nAlso, I have noticed that some admin pages take extremely long to load. For example the change page for a polygon annotation set. I think this happens because it has to load a lot of data which it does not do efficiently and because it makes all inline model fields are editable by default. It will most likely never happen that we need to change this data manually so those fields can all be set to read_only. It might also be better to just have some statistics there about the number of inline models and not show the actual inline models at all.\r\nExample loading time for an admin page:\r\n![image](https://user-images.githubusercontent.com/2001094/73462398-08bf9380-437c-11ea-9116-a6170c114176.png)\r\n\n", "before_files": [{"content": "from django.contrib import admin\n\nfrom grandchallenge.annotations.models import (\n    BooleanClassificationAnnotation,\n    ETDRSGridAnnotation,\n    LandmarkAnnotationSet,\n    MeasurementAnnotation,\n    PolygonAnnotationSet,\n    SingleLandmarkAnnotation,\n    SinglePolygonAnnotation,\n)\n\n\nclass BooleanClassificationAnnotationAdmin(admin.ModelAdmin):\n    search_fields = (\"grader__username\", \"name\", \"created\")\n    list_filter = (\"created\", \"value\", \"name\")\n\n\nclass SinglePolygonAnnotationInline(admin.StackedInline):\n    model = SinglePolygonAnnotation\n    extra = 0\n\n\nclass PolygonAnnotationSetAdmin(admin.ModelAdmin):\n    search_fields = (\"grader__username\", \"created\", \"name\")\n    list_filter = (\"created\", \"grader__username\", \"name\")\n    inlines = [SinglePolygonAnnotationInline]\n\n\nclass SingleLandmarkAnnotationInline(admin.StackedInline):\n    model = SingleLandmarkAnnotation\n    extra = 0\n\n\nclass LandmarkAnnotationSetAdmin(admin.ModelAdmin):\n    search_fields = (\"grader__username\", \"created\")\n    list_filter = (\"created\", \"grader__username\")\n    inlines = [SingleLandmarkAnnotationInline]\n\n\nadmin.site.register(ETDRSGridAnnotation)\nadmin.site.register(MeasurementAnnotation)\nadmin.site.register(\n    BooleanClassificationAnnotation, BooleanClassificationAnnotationAdmin\n)\nadmin.site.register(PolygonAnnotationSet, PolygonAnnotationSetAdmin)\nadmin.site.register(SinglePolygonAnnotation)\nadmin.site.register(LandmarkAnnotationSet, LandmarkAnnotationSetAdmin)\nadmin.site.register(SingleLandmarkAnnotation)\n", "path": "app/grandchallenge/annotations/admin.py"}]}