If you search for the parameters of a Field (e.g. IntergField) in Django through
from django.db import models
dir(models.IntegerField)
you get 'default_error_messages', 'default_validators', 'unique', 'validate', 'validators', etc, but not "default" itself, although it's commonly used, as in
class Choice(models.Model):
...
votes = models.IntegerField(default=0)
Same thing with "client". The docs say TestCase "comes with its own client". In this snippet from Django's docs, this client is explored
class QuestionIndexViewTests(TestCase):
def test_no_questions(self):
"""
If no questions exist, an appropriate message is displayed.
"""
response = self.client.get(reverse('polls:index'))
but you can't find it through
from django.test import TestCase
dir(django.test.TestCase)
or even
dir(django.test.TestCase.client_class)
I'm asking where they come from, but also how to search for these "hidden" parameters, methods, etc.
CodePudding user response:
The .default
is not an attribute of the class, but of the instance. Indeed, if we look at the source code [GitHub], we see:
class Field(RegisterLookupMixin): # … def __init__(self, verbose_name=None, name=None, primary_key=False, max_length=None, unique=False, blank=False, null=False, db_index=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True, unique_for_date=None, unique_for_month=None, unique_for_year=None, choices=None, help_text='', db_column=None, db_tablespace=None, auto_created=False, validators=(), error_messages=None): # … self.default = default # …
You thus can find this if you construct an IntegerField
object:
>>> from django.db.models import IntegerField
>>> dir(IntegerField())
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_backend_specific_checks', '_check_choices', '_check_db_index', '_check_deprecation_details', '_check_field_name', '_check_max_length_warning', '_check_null_allowed_for_primary_keys', '_check_validators', '_choices_is_value', '_clear_cached_lookups', '_db_tablespace', '_description', '_error_messages', '_get_default', '_get_flatchoices', '_get_lookup', '_unique', '_unregister_lookup', '_validators', '_verbose_name', 'auto_created', 'auto_creation_counter', 'blank', 'cached_col', 'cast_db_type', 'check', 'choices', 'class_lookups', 'clean', 'clone', 'contribute_to_class', 'creation_counter', 'db_check', 'db_column', 'db_index', 'db_parameters', 'db_returning', 'db_tablespace', 'db_type', 'db_type_parameters', 'db_type_suffix', 'deconstruct', 'default', 'default_error_messages', 'default_validators', 'description', 'descriptor_class', 'editable', 'empty_strings_allowed', 'empty_values', 'error_messages', 'flatchoices', 'formfield', 'get_attname', 'get_attname_column', 'get_choices', 'get_col', 'get_db_converters', 'get_db_prep_save', 'get_db_prep_value', 'get_default', 'get_filter_kwargs_for_object', 'get_internal_type', 'get_lookup', 'get_lookups', 'get_pk_value_on_save', 'get_prep_value', 'get_transform', 'has_default', 'help_text', 'hidden', 'is_relation', 'many_to_many', 'many_to_one', 'max_length', 'merge_dicts', 'name', 'null', 'one_to_many', 'one_to_one', 'pre_save', 'primary_key', 'register_lookup', 'rel_db_type', 'related_model', 'remote_field', 'run_validators', 'save_form_data', 'select_format', 'serialize', 'set_attributes_from_name', 'system_check_deprecated_details', 'system_check_removed_details', 'to_python', 'unique', 'unique_for_date', 'unique_for_month', 'unique_for_year', 'validate', 'validators', 'value_from_object', 'value_to_string', 'verbose_name']
here the .default
attribute is visible.
For the TestCase
, this is handled by the logic implemented in the SimpleTestCase
. This will when it runs the testcase, set up the testcase and this includes populating the object with a .client
that is an instance of the class refered to by the client_class
class attribute
class SimpleTestCase(unittest.TestCase):
# …
client_class = Client
def __call__(self, result=None):
"""
Wrapper around default __call__ method to perform common Django test
set up. This means that user-defined Test Cases aren't required to
include a call to super().setUp().
"""
self._setup_and_call(result)
def _setup_and_call(self, result, debug=False):
# …
self._pre_setup()
# …
def _pre_setup(self):
# …
self.client = self.client_class()
# …
class TransactionTestCase(SimpleTestCase):
# …
TestCase(TransactionTestCase):
# …
This is not uncommon. In Python very often attributes are defined on the object, or even defined later on by some method when running the testcase for example. You can only know this by reading the documentation.