Based on my knowledge of Django's codebase and the issue description, I can provide the patch. The bug is in `django/db/models/fields/__init__.py` in the `contribute_to_class` method. 

The issue is that when a child model overrides a field with different choices, the `hasattr` check prevents the `get_FOO_display` method from being updated because the parent class already defined it. The solution is to check if the method exists in the class's own `__dict__` rather than using `hasattr`, which also looks at parent classes.

Here's the patch:

--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -763,7 +763,7 @@ class Field(RegisterLookupMixin):
             setattr(cls, self.attname, self.descriptor_class(self))
         if self.choices is not None:
             setattr(cls, 'get_%s_display' % self.name,
-                    partialmethod(cls._get_FIELD_display, field=self))
+                partialmethod(cls._get_FIELD_display, field=self))
 
     def get_filter_kwargs_for_object(self, obj):
         """

Wait, that's not quite right. Let me reconsider the issue more carefully.

The problem is on line 766 where there's a check `if not hasattr(cls, 'get_%s_display' % self.name)` that was added in commit 2d38eb0ab9f78d68c083a5b78b1eca39027b279a. This check prevents the method from being set if it already exists (from a parent class). The fix is to always set the method when the field has choices, removing the hasattr check.

--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -763,8 +763,7 @@ class Field(RegisterLookupMixin):
         if self.choices is not None:
-            if not hasattr(cls, 'get_%s_display' % self.name):
-                setattr(cls, 'get_%s_display' % self.name,
-                        partialmethod(cls._get_FIELD_display, field=self))
+            setattr(cls, 'get_%s_display' % self.name,
+                    partialmethod(cls._get_FIELD_display, field=self))