1
+ import re
2
+ import os .path
3
+
4
+ from django import forms
5
+ from django .core .exceptions import ValidationError
6
+ from django .core .validators import URLValidator
7
+ from django .db import models
8
+ from django .db import IntegrityError
9
+ from django .template .defaultfilters import filesizeformat
10
+ from django .utils .translation import ugettext_lazy as _
11
+ from django .utils .encoding import smart_unicode
12
+ from django .utils import importlib
13
+
14
+ from select_url_field .choice_with_other import ChoiceWithOtherField
15
+
16
+ class SelectURLField (models .CharField ):
17
+ description = _ ("URL" )
18
+
19
+ def __init__ (self , verbose_name = None , name = None , ** kwargs ):
20
+ kwargs ['max_length' ] = kwargs .get ('max_length' , 200 )
21
+ # handle choices option:
22
+ # from custom_site.url_choices import get_url_choices
23
+ # link = SelectURLField(blank=True, choices=get_url_choices)
24
+ self ._has_choices = False
25
+ if 'choices' in kwargs :
26
+ self ._has_choices = True
27
+ self ._url_choices = kwargs .pop ('choices' )
28
+
29
+ models .CharField .__init__ (self , verbose_name , name , ** kwargs )
30
+ self .validators .append (SelectURLValidator ())
31
+
32
+ def formfield (self , ** kwargs ):
33
+ # As with CharField, this will cause URL validation to be performed twice
34
+ defaults = {
35
+ 'form_class' : SelectURLFormField ,
36
+ }
37
+ defaults .update (kwargs )
38
+ ## when choices given, use them.
39
+ ## when not, use global settings.
40
+ if self ._has_choices :
41
+ if callable (self ._url_choices ):
42
+ choices = self ._url_choices ()
43
+ else :
44
+ choices = self ._url_choices
45
+ else :
46
+ from django .conf import settings
47
+ mod_path , func_name = settings .URL_CHOICES_FUNC .rsplit ('.' , 1 )
48
+ mod = importlib .import_module (mod_path )
49
+ choices_func = getattr (mod , func_name )
50
+ choices = choices_func ()
51
+ required = not self .blank
52
+ return ChoiceWithOtherField (choices = choices , required = required )
53
+
54
+
55
+ def to_python (self , value ):
56
+ from django .conf import settings
57
+ if value :
58
+ domain = getattr (settings , 'SITE_DOMAIN' , '' )
59
+ if domain :
60
+ domain_pattern = r'^(?:http|ftp)s?://' + domain
61
+ domain_regex = re .compile (domain_pattern , re .IGNORECASE )
62
+ #match = domain_regex.search(value)
63
+ value = domain_regex .sub ('' , value )
64
+ return super (SelectURLField , self ).to_python (value )
65
+
66
+ #We need IxxyURLField so this is backwards compatible
67
+ IxxyURLField = SelectURLField
68
+
69
+ class SelectURLValidator (object ):
70
+ code = 'invalid'
71
+ regex = re .compile (r'(?:[/?]\S+)$' , re .IGNORECASE )
72
+
73
+ def __init__ (self ):
74
+ self .url_validator = URLValidator ()
75
+
76
+ def __call__ (self , value ):
77
+ try :
78
+ #OK if it's a valid url
79
+ self .url_validator (value )
80
+ except ValidationError , e :
81
+ #Not a valid url, see it's a path
82
+ if not self .regex .search (smart_unicode (value )):
83
+ raise e
84
+
85
+ class SelectURLFormField (forms .CharField ):
86
+ default_error_messages = {
87
+ 'invalid' : _ (u'Enter a valid URL.' ),
88
+ }
89
+
90
+ def __init__ (self , max_length = None , min_length = None , * args , ** kwargs ):
91
+ super (SelectURLFormField , self ).__init__ (max_length , min_length , * args , ** kwargs )
92
+ self .validators .append (SelectURLValidator ())
93
+
94
+
95
+ from south .modelsinspector import add_introspection_rules
96
+ add_introspection_rules ([], ["^select_url_field\.fields\.IxxyURLField" ])
97
+ add_introspection_rules ([], ["^select_url_field\.fields\.SelectURLField" ])
0 commit comments