Ticket #7977: admindocs_field_types.diff
File admindocs_field_types.diff, 15.4 KB (added by , 15 years ago) |
---|
-
django/db/models/fields/__init__.py
49 49 # getattr(obj, opts.pk.attname) 50 50 51 51 class Field(object): 52 """Base class for all field types""" 53 52 54 # Designates whether empty strings fundamentally are allowed at the 53 55 # database level. 54 56 empty_strings_allowed = True … … 340 342 return getattr(obj, self.attname) 341 343 342 344 class AutoField(Field): 345 """Integer""" 346 343 347 empty_strings_allowed = False 348 344 349 def __init__(self, *args, **kwargs): 345 350 assert kwargs.get('primary_key', False) is True, "%ss must have primary_key=True." % self.__class__.__name__ 346 351 kwargs['blank'] = True … … 370 375 return None 371 376 372 377 class BooleanField(Field): 378 """Boolean (Either True or False)""" 379 373 380 empty_strings_allowed = False 381 374 382 def __init__(self, *args, **kwargs): 375 383 kwargs['blank'] = True 376 384 if 'default' not in kwargs and not kwargs.get('null'): … … 413 421 return super(BooleanField, self).formfield(**defaults) 414 422 415 423 class CharField(Field): 424 """String (up to %(max_length)s)""" 425 416 426 def get_internal_type(self): 417 427 return "CharField" 418 428 … … 434 444 435 445 # TODO: Maybe move this into contrib, because it's specialized. 436 446 class CommaSeparatedIntegerField(CharField): 447 """Comma-separated integers""" 448 437 449 def formfield(self, **kwargs): 438 450 defaults = { 439 451 'form_class': forms.RegexField, … … 449 461 ansi_date_re = re.compile(r'^\d{4}-\d{1,2}-\d{1,2}$') 450 462 451 463 class DateField(Field): 464 """Date (without time)""" 465 452 466 empty_strings_allowed = False 467 453 468 def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs): 454 469 self.auto_now, self.auto_now_add = auto_now, auto_now_add 455 470 #HACKs : auto_now_add/auto_now should be done as a default or a pre_save. … … 524 539 return super(DateField, self).formfield(**defaults) 525 540 526 541 class DateTimeField(DateField): 542 """Date (with time)""" 543 527 544 def get_internal_type(self): 528 545 return "DateTimeField" 529 546 … … 583 600 return super(DateTimeField, self).formfield(**defaults) 584 601 585 602 class DecimalField(Field): 603 """Decimal number""" 604 586 605 empty_strings_allowed = False 606 587 607 def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs): 588 608 self.max_digits, self.decimal_places = max_digits, decimal_places 589 609 Field.__init__(self, verbose_name, name, **kwargs) … … 637 657 return super(DecimalField, self).formfield(**defaults) 638 658 639 659 class EmailField(CharField): 660 """E-mail address""" 661 640 662 def __init__(self, *args, **kwargs): 641 663 kwargs['max_length'] = kwargs.get('max_length', 75) 642 664 CharField.__init__(self, *args, **kwargs) … … 647 669 return super(EmailField, self).formfield(**defaults) 648 670 649 671 class FilePathField(Field): 672 """File path""" 673 650 674 def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs): 651 675 self.path, self.match, self.recursive = path, match, recursive 652 676 kwargs['max_length'] = kwargs.get('max_length', 100) … … 666 690 return "FilePathField" 667 691 668 692 class FloatField(Field): 693 """Floating point number""" 694 669 695 empty_strings_allowed = False 670 696 671 697 def get_db_prep_value(self, value): … … 691 717 return super(FloatField, self).formfield(**defaults) 692 718 693 719 class IntegerField(Field): 720 """Integer""" 721 694 722 empty_strings_allowed = False 723 695 724 def get_db_prep_value(self, value): 696 725 if value is None: 697 726 return None … … 715 744 return super(IntegerField, self).formfield(**defaults) 716 745 717 746 class IPAddressField(Field): 747 """IP address""" 748 718 749 empty_strings_allowed = False 750 719 751 def __init__(self, *args, **kwargs): 720 752 kwargs['max_length'] = 15 721 753 Field.__init__(self, *args, **kwargs) … … 729 761 return super(IPAddressField, self).formfield(**defaults) 730 762 731 763 class NullBooleanField(Field): 764 """Boolean (Either True, False or None)""" 765 732 766 empty_strings_allowed = False 767 733 768 def __init__(self, *args, **kwargs): 734 769 kwargs['null'] = True 735 770 Field.__init__(self, *args, **kwargs) … … 769 804 return super(NullBooleanField, self).formfield(**defaults) 770 805 771 806 class PositiveIntegerField(IntegerField): 807 """Integer""" 808 772 809 def get_internal_type(self): 773 810 return "PositiveIntegerField" 774 811 … … 778 815 return super(PositiveIntegerField, self).formfield(**defaults) 779 816 780 817 class PositiveSmallIntegerField(IntegerField): 818 """Integer""" 819 781 820 def get_internal_type(self): 782 821 return "PositiveSmallIntegerField" 783 822 … … 787 826 return super(PositiveSmallIntegerField, self).formfield(**defaults) 788 827 789 828 class SlugField(CharField): 829 """String (up to %(max_length)s)""" 830 790 831 def __init__(self, *args, **kwargs): 791 832 kwargs['max_length'] = kwargs.get('max_length', 50) 792 833 # Set db_index=True unless it's been set manually. … … 803 844 return super(SlugField, self).formfield(**defaults) 804 845 805 846 class SmallIntegerField(IntegerField): 847 """Integer""" 848 806 849 def get_internal_type(self): 807 850 return "SmallIntegerField" 808 851 809 852 class TextField(Field): 853 """Text""" 854 810 855 def get_internal_type(self): 811 856 return "TextField" 812 857 … … 816 861 return super(TextField, self).formfield(**defaults) 817 862 818 863 class TimeField(Field): 864 """Time""" 865 819 866 empty_strings_allowed = False 867 820 868 def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs): 821 869 self.auto_now, self.auto_now_add = auto_now, auto_now_add 822 870 if auto_now or auto_now_add: … … 888 936 return super(TimeField, self).formfield(**defaults) 889 937 890 938 class URLField(CharField): 939 """URL""" 940 891 941 def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs): 892 942 kwargs['max_length'] = kwargs.get('max_length', 200) 893 943 self.verify_exists = verify_exists … … 899 949 return super(URLField, self).formfield(**defaults) 900 950 901 951 class XMLField(TextField): 952 """XML text""" 953 902 954 def __init__(self, verbose_name=None, name=None, schema_path=None, **kwargs): 903 955 self.schema_path = schema_path 904 956 Field.__init__(self, verbose_name, name, **kwargs) -
django/db/models/fields/related.py
682 682 return self.to._meta.pk 683 683 684 684 class ForeignKey(RelatedField, Field): 685 """Foreign Key (type determined by related field)""" 686 685 687 empty_strings_allowed = False 686 688 def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs): 687 689 try: … … 771 773 return rel_field.db_type() 772 774 773 775 class OneToOneField(ForeignKey): 774 """ 775 A OneToOneField is essentially the same as a ForeignKey, with the exception 776 that always carries a "unique" constraint with it and the reverse relation 777 always returns the object pointed to (since there will only ever be one), 778 rather than returning a list. 779 """ 776 """One-to-one relationship""" 777 778 # A OneToOneField is essentially the same as a ForeignKey, with the exception 779 # that always carries a "unique" constraint with it and the reverse relation 780 # always returns the object pointed to (since there will only ever be one), 781 # rather than returning a list. 782 780 783 def __init__(self, to, to_field=None, **kwargs): 781 784 kwargs['unique'] = True 782 785 super(OneToOneField, self).__init__(to, to_field, OneToOneRel, **kwargs) … … 791 794 return super(OneToOneField, self).formfield(**kwargs) 792 795 793 796 class ManyToManyField(RelatedField, Field): 797 """Many-to-many relationship""" 798 794 799 def __init__(self, to, **kwargs): 795 800 try: 796 801 assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name) -
django/db/models/fields/files.py
209 209 instance.__dict__[self.field.name] = value 210 210 211 211 class FileField(Field): 212 """File path""" 213 212 214 # The class to wrap instance attributes in. Accessing the file object off 213 215 # the instance will always return an instance of attr_class. 214 216 attr_class = FieldFile … … 323 325 super(ImageFieldFile, self).delete(save) 324 326 325 327 class ImageField(FileField): 328 """File path""" 329 326 330 attr_class = ImageFieldFile 327 331 descriptor_class = ImageFileDescriptor 328 332 -
django/contrib/gis/db/models/fields/__init__.py
30 30 return _srid_cache[srid] 31 31 32 32 class GeometryField(SpatialBackend.Field): 33 " The base GIS field -- maps to the OpenGIS Specification Geometry type."33 """The base GIS field -- maps to the OpenGIS Specification Geometry type.""" 34 34 35 35 # The OpenGIS Geometry name. 36 36 geom_type = 'GEOMETRY' … … 257 257 258 258 # The OpenGIS Geometry Type Fields 259 259 class PointField(GeometryField): 260 """Point""" 260 261 geom_type = 'POINT' 261 262 262 263 class LineStringField(GeometryField): 264 """Line string""" 263 265 geom_type = 'LINESTRING' 264 266 265 267 class PolygonField(GeometryField): 268 """Polygon""" 266 269 geom_type = 'POLYGON' 267 270 268 271 class MultiPointField(GeometryField): 272 """Multi-point""" 269 273 geom_type = 'MULTIPOINT' 270 274 271 275 class MultiLineStringField(GeometryField): 276 """Multi-line string""" 272 277 geom_type = 'MULTILINESTRING' 273 278 274 279 class MultiPolygonField(GeometryField): 280 """Multi polygon""" 275 281 geom_type = 'MULTIPOLYGON' 276 282 277 283 class GeometryCollectionField(GeometryField): 284 """Geometry collection""" 278 285 geom_type = 'GEOMETRYCOLLECTION' -
django/contrib/admindocs/views.py
307 307 return 'Integer' 308 308 return '' 309 309 310 # Maps Field objects to their human-readable data types, as strings.311 # Column-type strings can contain format strings; they'll be interpolated312 # against the values of Field.__dict__ before being output.313 # If a column type is set to None, it won't be included in the output.314 DATA_TYPE_MAPPING = {315 'AutoField' : _('Integer'),316 'BooleanField' : _('Boolean (Either True or False)'),317 'CharField' : _('String (up to %(max_length)s)'),318 'CommaSeparatedIntegerField': _('Comma-separated integers'),319 'DateField' : _('Date (without time)'),320 'DateTimeField' : _('Date (with time)'),321 'DecimalField' : _('Decimal number'),322 'EmailField' : _('E-mail address'),323 'FileField' : _('File path'),324 'FilePathField' : _('File path'),325 'FloatField' : _('Floating point number'),326 'ForeignKey' : _('Integer'),327 'ImageField' : _('File path'),328 'IntegerField' : _('Integer'),329 'IPAddressField' : _('IP address'),330 'ManyToManyField' : '',331 'NullBooleanField' : _('Boolean (Either True, False or None)'),332 'OneToOneField' : _('Relation to parent model'),333 'PhoneNumberField' : _('Phone number'),334 'PositiveIntegerField' : _('Integer'),335 'PositiveSmallIntegerField' : _('Integer'),336 'SlugField' : _('String (up to %(max_length)s)'),337 'SmallIntegerField' : _('Integer'),338 'TextField' : _('Text'),339 'TimeField' : _('Time'),340 'URLField' : _('URL'),341 'USStateField' : _('U.S. state (two uppercase letters)'),342 'XMLField' : _('XML text'),343 }344 345 310 def get_readable_field_data_type(field): 346 return DATA_TYPE_MAPPING[field.get_internal_type()] % field.__dict__ 311 """Returns the doc string for a given field type, if it exists, 312 Fields' docstrings can contain format strings, which will be interpolated 313 against the values of Field.__dict__ before being output. If no docstring 314 is given, a sensible value will be auto-generated from the field's class 315 name.""" 347 316 317 if field.__doc__: 318 return _(field.__doc__) % field.__dict__ 319 else: 320 return _(u'Field of type: %(field_type)s') % { 321 'field_type': field.__class__.__name__ 322 } 323 348 324 def extract_views_from_urlpatterns(urlpatterns, base=''): 349 325 """ 350 326 Return a list of views from a list of urlpatterns. -
django/contrib/admindocs/tests.py
1 import unittest 2 import views 3 from django.db.models import fields as builtin_fields 4 #import django.contrib.gis.db.models.fields as gis_fields 5 import models 6 7 8 class TestFieldType(unittest.TestCase): 9 def setUp(self): 10 pass 11 12 def test_field_name(self): 13 self.assertRaises(AttributeError, 14 views.get_readable_field_data_type, "NotAField" 15 ) 16 17 def test_builtin_fields(self): 18 self.assertEqual( 19 views.get_readable_field_data_type(builtin_fields.BooleanField()), 20 u'Boolean (Either True or False)' 21 ) 22 23 #def test_gis_fields(self): 24 # self.assertEqual( 25 # views.get_readable_field_data_type(gis_fields.PolygonField), 26 # u'Polygon!' 27 # ) 28 29 def test_custom_fields(self): 30 self.assertEqual( 31 views.get_readable_field_data_type(models.CustomField()), 32 u'A custom field type' 33 ) 34 self.assertEqual( 35 views.get_readable_field_data_type(models.DocstringLackingField()), 36 u'Field of type: DocstringLackingField' 37 ) -
django/contrib/admindocs/models.py
1 2 from django.db import models 3 4 class CustomField(models.Field): 5 """A custom field type""" 6 7 class DocstringLackingField(models.Field): 8 pass -
django/contrib/localflavor/us/models.py
2 2 from django.db.models.fields import Field 3 3 4 4 class USStateField(Field): 5 """U.S. state (two uppercase letters)""" 5 6 def get_internal_type(self): 6 7 return "USStateField" 7 8 … … 18 19 return super(USStateField, self).formfield(**defaults) 19 20 20 21 class PhoneNumberField(Field): 22 """Phone number""" 21 23 def get_internal_type(self): 22 24 return "PhoneNumberField" 23 25