11import base64
22import os
3+ import re
34import uuid
45from string import Formatter
56
1011
1112
1213class SlugFormatter (Formatter ):
14+ format_spec_pattern = re .compile (r'(\.\d+)?([\d\w]+)?' )
1315
1416 def format_field (self , value , format_spec ):
15- if format_spec == 'slug' :
16- return slugify (value )
17+ precision , ftype = self .format_spec_pattern .match (format_spec ).groups ()
18+ if precision :
19+ precision = int (precision .lstrip ('.' ))
20+ if ftype == 'slug' :
21+ return slugify (value )[:precision ]
1722 return super ().format_field (value = value , format_spec = format_spec )
1823
1924
2025class ExtendedUUID (uuid .UUID ):
26+ format_spec_pattern = re .compile (r'(\.\d+)?([\d\w]+)?' )
2127
2228 def __format__ (self , format_spec ):
23- if format_spec == '' :
24- return str (self )
25- if format_spec == 's' :
26- return str (self )
27- if format_spec == 'i' :
28- return str (self .int )
29- if format_spec == 'x' :
30- return self .hex .lower ()
31- if format_spec == 'X' :
32- return self .hex .upper ()
33- if format_spec == 'base32' :
29+ precision , ftype = self .format_spec_pattern .match (format_spec ).groups ()
30+ if precision :
31+ precision = int (precision .lstrip ('.' ))
32+ if ftype == '' :
33+ return str (self )[:precision ]
34+ if ftype == 's' :
35+ return str (self )[:precision ]
36+ if ftype == 'i' :
37+ return str (self .int )[:precision ]
38+ if ftype == 'x' :
39+ return self .hex .lower ()[:precision ]
40+ if ftype == 'X' :
41+ return self .hex .upper ()[:precision ]
42+ if ftype == 'base32' :
3443 return base64 .b32encode (
3544 self .bytes
36- ).decode ('utf-8' ).rstrip ('=\n ' )
37- if format_spec == 'base64' :
45+ ).decode ('utf-8' ).rstrip ('=\n ' )[: precision ]
46+ if ftype == 'base64' :
3847 return base64 .urlsafe_b64encode (
3948 self .bytes
40- ).decode ('utf-8' ).rstrip ('=\n ' )
49+ ).decode ('utf-8' ).rstrip ('=\n ' )[: precision ]
4150 return super ().__format__ (format_spec )
4251
4352
4453class FilePattern :
4554 """
46- Write advanced filename patterns using the Format Specification Mini-Language .
55+ Write advanced filename patterns using the Format String Syntax .
4756
4857 Basic example:
4958
@@ -52,7 +61,7 @@ class FilePattern:
5261 from django.db import models
5362 from dynamic_names import FilePattern
5463
55- upload_to_pattern = FilePattern('{app_name:.25}/{model_name:.30}/{uuid:base32 }{ext}')
64+ upload_to_pattern = FilePattern('{app_name:.25}/{model_name:.30}/{uuid:.30base32 }{ext}')
5665
5766 class FileModel(models.Model):
5867 my_file = models.FileField(upload_to=upload_to_pattern)
0 commit comments