44from django import forms
55from django .conf import settings
66from django .contrib .contenttypes .models import ContentType
7- from django .core .urlresolvers import reverse
87from django .db .models .query import QuerySet
9- try :
10- from django .forms .utils import flatatt
11- except ImportError :
12- # < django 1.7
13- from django .forms .util import flatatt
14- from django .template .loader import render_to_string
8+ from django .forms .utils import flatatt
159from django .template .defaultfilters import force_escape
10+ from django .template .loader import render_to_string
1611from django .utils .encoding import force_text
1712from django .utils .safestring import mark_safe
1813from django .utils .six import text_type
1914from django .utils .translation import ugettext as _
15+ try :
16+ from django .urls import reverse
17+ except ImportError :
18+ # < django 1.10
19+ from django .core .urlresolvers import reverse
2020
2121
2222as_default_help = 'Enter text to search.'
@@ -35,12 +35,14 @@ def _media(self):
3535 return forms .Media (css = {'all' : ('ajax_select/css/ajax_select.css' ,)}, js = js )
3636
3737
38- ####################################################################################
38+ ###############################################################################
3939
4040
4141class AutoCompleteSelectWidget (forms .widgets .TextInput ):
4242
43- """Widget to search for a model and return it as text for use in a CharField."""
43+ """
44+ Widget to search for a model and return it as text for use in a CharField.
45+ """
4446
4547 media = property (_media )
4648
@@ -61,7 +63,10 @@ def __init__(self,
6163
6264 def render (self , name , value , attrs = None ):
6365 value = value or ''
64- final_attrs = self .build_attrs (attrs )
66+
67+ final_attrs = self .build_attrs (self .attrs )
68+ final_attrs .update (attrs or {})
69+ final_attrs .pop ('required' , None )
6570 self .html_id = final_attrs .pop ('id' , name )
6671
6772 current_repr = ''
@@ -131,7 +136,8 @@ def clean(self, value):
131136 if len (objs ) != 1 :
132137 # someone else might have deleted it while you were editing
133138 # or your channel is faulty
134- # out of the scope of this field to do anything more than tell you it doesn't exist
139+ # out of the scope of this field to do anything more than
140+ # tell you it doesn't exist
135141 raise forms .ValidationError ("%s cannot find object: %s" % (lookup , value ))
136142 return objs [0 ]
137143 else :
@@ -149,12 +155,14 @@ def has_changed(self, initial, data):
149155 return text_type (initial_value ) != text_type (data_value )
150156
151157
152- ####################################################################################
158+ ###############################################################################
153159
154160
155161class AutoCompleteSelectMultipleWidget (forms .widgets .SelectMultiple ):
156162
157- """Widget to select multiple models for a ManyToMany db field."""
163+ """
164+ Widget to select multiple models for a ManyToMany db field.
165+ """
158166
159167 media = property (_media )
160168
@@ -179,7 +187,9 @@ def render(self, name, value, attrs=None):
179187 if value is None :
180188 value = []
181189
182- final_attrs = self .build_attrs (attrs )
190+ final_attrs = self .build_attrs (self .attrs )
191+ final_attrs .update (attrs or {})
192+ final_attrs .pop ('required' , None )
183193 self .html_id = final_attrs .pop ('id' , name )
184194
185195 lookup = registry .get (self .channel )
@@ -229,7 +239,9 @@ def id_for_label(self, id_):
229239
230240class AutoCompleteSelectMultipleField (forms .fields .CharField ):
231241
232- """ form field to select multiple models for a ManyToMany db field """
242+ """
243+ Form field to select multiple models for a ManyToMany db field.
244+ """
233245
234246 channel = None
235247
@@ -245,8 +257,8 @@ def __init__(self, channel, *args, **kwargs):
245257 if isinstance (help_text , str ):
246258 help_text = force_text (help_text )
247259 # django admin appends "Hold down "Control",..." to the help text
248- # regardless of which widget is used. so even when you specify an explicit
249- # help text it appends this other default text onto the end.
260+ # regardless of which widget is used. so even when you specify an
261+ # explicit help text it appends this other default text onto the end.
250262 # This monkey patches the help text to remove that
251263 if help_text != '' :
252264 if not isinstance (help_text , text_type ):
@@ -298,14 +310,15 @@ def has_changed(self, initial_value, data_value):
298310 dvs = [text_type (v ) for v in (data_value or [])]
299311 return ivs != dvs
300312
301- ####################################################################################
313+ ###############################################################################
302314
303315
304316class AutoCompleteWidget (forms .TextInput ):
305317
306318 """
307- Widget to select a search result and enter the result as raw text in the text input field.
308- the user may also simply enter text and ignore any auto complete suggestions.
319+ Widget to select a search result and enter the result as raw text in the
320+ text input field. The user may also simply enter text and ignore any
321+ auto complete suggestions.
309322 """
310323
311324 media = property (_media )
@@ -325,9 +338,10 @@ def __init__(self, channel, *args, **kwargs):
325338 def render (self , name , value , attrs = None ):
326339
327340 initial = value or ''
328-
329- final_attrs = self . build_attrs (attrs )
341+ final_attrs = self . build_attrs ( self . attrs )
342+ final_attrs . update (attrs or {} )
330343 self .html_id = final_attrs .pop ('id' , name )
344+ final_attrs .pop ('required' , None )
331345
332346 lookup = registry .get (self .channel )
333347 if self .show_help_text :
@@ -352,7 +366,8 @@ def render(self, name, value, attrs=None):
352366
353367class AutoCompleteField (forms .CharField ):
354368 """
355- A CharField that uses an AutoCompleteWidget to lookup matching and stores the result as plain text.
369+ A CharField that uses an AutoCompleteWidget to lookup matching
370+ and stores the result as plain text.
356371 """
357372 channel = None
358373
@@ -375,7 +390,7 @@ def __init__(self, channel, *args, **kwargs):
375390 super (AutoCompleteField , self ).__init__ (* args , ** defaults )
376391
377392
378- ####################################################################################
393+ ###############################################################################
379394
380395def _check_can_add (self , user , related_model ):
381396 """
@@ -402,7 +417,8 @@ def _check_can_add(self, user, related_model):
402417def autoselect_fields_check_can_add (form , model , user ):
403418 """
404419 Check the form's fields for any autoselect fields and enable their
405- widgets with green + button if permissions allow then to create the related_model.
420+ widgets with green + button if permissions allow then to create the
421+ related_model.
406422 """
407423 for name , form_field in form .declared_fields .items ():
408424 if isinstance (form_field , (AutoCompleteSelectMultipleField , AutoCompleteSelectField )):
0 commit comments