22
33import attrs
44from django import http
5+ from django .db import models
56from django .urls import reverse
67from django .views .generic import RedirectView , TemplateView , View
78
8- from cbv .models import DjangoURLService , Klass , Module , ProjectVersion
9+ from cbv .models import DjangoURLService , Klass , KlassAttribute , Module , ProjectVersion
910from cbv .queries import NavBuilder
1011
1112
@@ -87,7 +88,7 @@ def get_context_data(self, **kwargs):
8788 return {
8889 "all_ancestors" : ancestors ,
8990 "all_children" : children ,
90- "attributes" : klass .get_prepared_attributes (),
91+ "attributes" : self .get_prepared_attributes (klass ),
9192 "canonical_url" : self .request .build_absolute_uri (canonical_url_path ),
9293 "klass" : klass ,
9394 "methods" : list (klass .get_methods ()),
@@ -98,6 +99,42 @@ def get_context_data(self, **kwargs):
9899 "yuml_url" : klass .basic_yuml_url (),
99100 }
100101
102+ def get_prepared_attributes (
103+ self , class_ : Klass
104+ ) -> models .QuerySet ["KlassAttribute" ]:
105+ attributes = class_ .get_attributes ()
106+ # Make a dictionary of attributes based on name
107+ attribute_names : dict [str , list [KlassAttribute ]] = {}
108+ for attr in attributes :
109+ try :
110+ attribute_names [attr .name ] += [attr ]
111+ except KeyError :
112+ attribute_names [attr .name ] = [attr ]
113+
114+ ancestors = class_ .get_all_ancestors ()
115+
116+ # Find overridden attributes
117+ for name , attrs_ in attribute_names .items ():
118+ # Skip if we have only one attribute.
119+ if len (attrs_ ) == 1 :
120+ continue
121+
122+ # Sort the attributes by ancestors.
123+ def _key (a : KlassAttribute ) -> int :
124+ try :
125+ # If ancestor, return the index (>= 0)
126+ return ancestors .index (a .klass )
127+ except ValueError : # Raised by .index if item is not in list.
128+ # else a.klass == self, so return -1
129+ return - 1
130+
131+ sorted_attrs = sorted (attrs_ , key = _key )
132+
133+ # Mark overriden KlassAttributes
134+ for a in sorted_attrs [1 :]:
135+ a .overridden = True
136+ return attributes
137+
101138
102139class LatestKlassRedirectView (RedirectView ):
103140 def get_redirect_url (self , ** kwargs ):
0 commit comments