Changeset 3258
- Timestamp:
- 07/03/06 09:23:39 (2 years ago)
- Files:
-
- django/branches/multiple-db-support/django/conf/global_settings.py (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/admin/templates/admin/base.html (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/admin/urls.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/contrib/auth/__init__.py (modified) (3 diffs)
- django/branches/multiple-db-support/django/contrib/markup/templatetags/markup.py (modified) (1 diff)
- django/branches/multiple-db-support/django/core/serializers/base.py (modified) (1 diff)
- django/branches/multiple-db-support/django/core/serializers/__init__.py (modified) (1 diff)
- django/branches/multiple-db-support/django/core/serializers/json.py (copied) (copied from django/trunk/django/core/serializers/json.py)
- django/branches/multiple-db-support/django/core/serializers/python.py (copied) (copied from django/trunk/django/core/serializers/python.py)
- django/branches/multiple-db-support/django/core/serializers/xml_serializer.py (modified) (4 diffs)
- django/branches/multiple-db-support/django/db/backends/oracle/base.py (modified) (1 diff)
- django/branches/multiple-db-support/django/db/models/fields/__init__.py (modified) (3 diffs)
- django/branches/multiple-db-support/django/db/models/fields/related.py (modified) (1 diff)
- django/branches/multiple-db-support/django/db/models/loading.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/db/models/query.py (modified) (5 diffs)
- django/branches/multiple-db-support/django/db/models/related.py (modified) (1 diff)
- django/branches/multiple-db-support/django/utils/simplejson (copied) (copied from django/trunk/django/utils/simplejson)
- django/branches/multiple-db-support/django/utils/simplejson/decoder.py (copied) (copied from django/trunk/django/utils/simplejson/decoder.py)
- django/branches/multiple-db-support/django/utils/simplejson/encoder.py (copied) (copied from django/trunk/django/utils/simplejson/encoder.py)
- django/branches/multiple-db-support/django/utils/simplejson/__init__.py (copied) (copied from django/trunk/django/utils/simplejson/__init__.py)
- django/branches/multiple-db-support/django/utils/simplejson/LICENSE.txt (copied) (copied from django/trunk/django/utils/simplejson/LICENSE.txt)
- django/branches/multiple-db-support/django/utils/simplejson/scanner.py (copied) (copied from django/trunk/django/utils/simplejson/scanner.py)
- django/branches/multiple-db-support/django/views/i18n.py (modified) (3 diffs)
- django/branches/multiple-db-support/docs/add_ons.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/authentication.txt (modified) (5 diffs)
- django/branches/multiple-db-support/docs/faq.txt (modified) (2 diffs)
- django/branches/multiple-db-support/docs/i18n.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/serialization.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/settings.txt (modified) (3 diffs)
- django/branches/multiple-db-support/tests/modeltests/many_to_many/models.py (modified) (3 diffs)
- django/branches/multiple-db-support/tests/modeltests/many_to_one/models.py (modified) (5 diffs)
- django/branches/multiple-db-support/tests/modeltests/one_to_one/models.py (modified) (4 diffs)
- django/branches/multiple-db-support/tests/modeltests/serializers/models.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/multiple-db-support/django/conf/global_settings.py
r3239 r3258 68 68 LANGUAGES_BIDI = ("he",) 69 69 70 # If you set this to False, Django will make some optimizations so as not 71 # to load the internationalization machinery. 72 USE_I18N = True 73 70 74 # Not-necessarily-technical managers of the site. They get broken link 71 75 # notifications and other various e-mails. django/branches/multiple-db-support/django/contrib/admin/templates/admin/base.html
r3129 r3258 44 44 <!-- END Content --> 45 45 46 <div id="footer"></div>46 {% block footer %}<div id="footer"></div>{% endblock %} 47 47 </div> 48 48 <!-- END Container --> django/branches/multiple-db-support/django/contrib/admin/urls.py
r3009 r3258 1 from django.conf import settings 1 2 from django.conf.urls.defaults import * 3 4 if settings.USE_I18N: 5 i18n_view = 'django.views.i18n.javascript_catalog' 6 else: 7 i18n_view = 'django.views.i18n.null_javascript_catalog' 2 8 3 9 urlpatterns = patterns('', 4 10 ('^$', 'django.contrib.admin.views.main.index'), 5 11 ('^r/(\d+)/(.*)/$', 'django.views.defaults.shortcut'), 6 ('^jsi18n/$', 'django.views.i18n.javascript_catalog', {'packages': 'django.conf'}),12 ('^jsi18n/$', i18n_view, {'packages': 'django.conf'}), 7 13 ('^logout/$', 'django.contrib.auth.views.logout'), 8 14 ('^password_change/$', 'django.contrib.auth.views.password_change'), … … 30 36 ('^([^/]+)/([^/]+)/(.+)/$', 'django.contrib.admin.views.main.change_stage'), 31 37 ) 38 39 del i18n_view django/branches/multiple-db-support/django/contrib/auth/__init__.py
r3228 r3258 28 28 def authenticate(**credentials): 29 29 """ 30 If the given credentials , return a user object.30 If the given credentials are valid, return a User object. 31 31 """ 32 32 for backend in get_backends(): … … 34 34 user = backend.authenticate(**credentials) 35 35 except TypeError: 36 # this backend doesn't accept these credentials as arguments, try the next one.36 # This backend doesn't accept these credentials as arguments. Try the next one. 37 37 continue 38 38 if user is None: 39 39 continue 40 # annotate the user object with the path of the backend40 # Annotate the user object with the path of the backend. 41 41 user.backend = str(backend.__class__) 42 42 return user … … 55 55 def logout(request): 56 56 """ 57 Remove the authenticated user's id fromrequest.57 Remove the authenticated user's ID from the request. 58 58 """ 59 59 del request.session[SESSION_KEY] django/branches/multiple-db-support/django/contrib/markup/templatetags/markup.py
r3228 r3258 48 48 return value 49 49 else: 50 parts = publish_parts(source=value, writer_name="html4css1") 50 docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {}) 51 parts = publish_parts(source=value, writer_name="html4css1", settings_overrides=docutils_settings) 51 52 return parts["fragment"] 52 53 django/branches/multiple-db-support/django/core/serializers/base.py
r3228 r3258 34 34 self.start_object(obj) 35 35 for field in obj._meta.fields: 36 if field.rel is None: 36 if field is obj._meta.pk: 37 continue 38 elif field.rel is None: 37 39 self.handle_field(obj, field) 38 40 else: django/branches/multiple-db-support/django/core/serializers/__init__.py
r3228 r3258 21 21 # Built-in serializers 22 22 BUILTIN_SERIALIZERS = { 23 "xml" : "django.core.serializers.xml_serializer", 23 "xml" : "django.core.serializers.xml_serializer", 24 "python" : "django.core.serializers.python", 25 "json" : "django.core.serializers.json", 24 26 } 25 27 django/branches/multiple-db-support/django/core/serializers/xml_serializer.py
r3228 r3258 3 3 """ 4 4 5 from xml.dom import pulldom 6 from django.utils.xmlutils import SimplerXMLGenerator 5 from django.conf import settings 7 6 from django.core.serializers import base 8 7 from django.db import models 8 from django.utils.xmlutils import SimplerXMLGenerator 9 from xml.dom import pulldom 9 10 10 11 class Serializer(base.Serializer): … … 17 18 Start serialization -- open the XML document and the root element. 18 19 """ 19 self.xml = SimplerXMLGenerator(self.stream, self.options.get("encoding", "utf-8"))20 self.xml = SimplerXMLGenerator(self.stream, self.options.get("encoding", settings.DEFAULT_CHARSET)) 20 21 self.xml.startDocument() 21 22 self.xml.startElement("django-objects", {"version" : "1.0"}) … … 59 60 # serializer base class). None is handled specially. 60 61 value = self.get_string_value(obj, field) 61 if value is None: 62 self.xml.addQuickElement("None") 63 else: 62 if value is not None: 64 63 self.xml.characters(str(value)) 65 64 … … 107 106 def __init__(self, stream_or_string, **options): 108 107 super(Deserializer, self).__init__(stream_or_string, **options) 109 self.encoding = self.options.get("encoding", "utf-8")108 self.encoding = self.options.get("encoding", settings.DEFAULT_CHARSET) 110 109 self.event_stream = pulldom.parse(self.stream) 111 110 django/branches/multiple-db-support/django/db/backends/oracle/base.py
r3229 r3258 124 124 'contains': 'LIKE %s', 125 125 'icontains': 'LIKE %s', 126 'ne': '!= %s',127 126 'gt': '> %s', 128 127 'gte': '>= %s', django/branches/multiple-db-support/django/db/models/fields/__init__.py
r3228 r3258 7 7 from django.utils.functional import curry, lazy 8 8 from django.utils.text import capfirst 9 from django.utils.translation import gettext, gettext_lazy , ngettext9 from django.utils.translation import gettext, gettext_lazy 10 10 import datetime, os, time 11 11 … … 163 163 def get_db_prep_lookup(self, lookup_type, value): 164 164 "Returns field's value prepared for database lookup." 165 if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', ' ne', 'year', 'month', 'day', 'search'):165 if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'year', 'month', 'day', 'search'): 166 166 return [value] 167 167 elif lookup_type in ('range', 'in'): … … 407 407 return value 408 408 validators.isValidANSIDate(value, None) 409 return datetime.date(*time.strptime(value, '%Y-%m-%d')[:3]) 409 try: 410 return datetime.date(*time.strptime(value, '%Y-%m-%d')[:3]) 411 except ValueError: 412 raise validators.ValidationError, gettext('Enter a valid date in YYYY-MM-DD format.') 410 413 411 414 def get_db_prep_lookup(self, lookup_type, value): 412 415 if lookup_type == 'range': 413 416 value = [str(v) for v in value] 414 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte' , 'ne') and hasattr(value, 'strftime'):417 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte') and hasattr(value, 'strftime'): 415 418 value = value.strftime('%Y-%m-%d') 416 419 else: django/branches/multiple-db-support/django/db/models/fields/related.py
r3234 r3258 79 79 self.contribute_to_related_class(other, related) 80 80 81 def get_db_prep_lookup(self, lookup_type, value): 82 # If we are doing a lookup on a Related Field, we must be 83 # comparing object instances. The value should be the PK of value, 84 # not value itself. 85 def pk_trace(value): 86 # Value may be a primary key, or an object held in a relation. 87 # If it is an object, then we need to get the primary key value for 88 # that object. In certain conditions (especially one-to-one relations), 89 # the primary key may itself be an object - so we need to keep drilling 90 # down until we hit a value that can be used for a comparison. 91 v = value 92 try: 93 while True: 94 v = getattr(v, v._meta.pk.name) 95 except AttributeError: 96 pass 97 return v 98 99 if lookup_type == 'exact': 100 return [pk_trace(value)] 101 if lookup_type == 'in': 102 return [pk_trace(v) for v in value] 103 elif lookup_type == 'isnull': 104 return [] 105 raise TypeError, "Related Field has invalid lookup: %s" % lookup_type 106 81 107 def _get_related_query_name(self, opts): 82 108 # This method defines the name that can be used to identify this related object django/branches/multiple-db-support/django/db/models/loading.py
r3228 r3258 16 16 # Key is the app_name of the model, value is the exception that was raised 17 17 # during model loading. 18 _loaded = False # Has the contents of settings.INSTALLED_APPS been loaded? 18 _loaded = False # Has the contents of settings.INSTALLED_APPS been loaded? 19 19 # i.e., has get_apps() been called? 20 20 … … 61 61 get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish. 62 62 return _app_errors 63 63 64 64 def get_models(app_mod=None): 65 65 """ django/branches/multiple-db-support/django/db/models/query.py
r3234 r3258 11 11 from sets import Set as set 12 12 13 # The string constant used to separate query parts 13 14 LOOKUP_SEPARATOR = '__' 15 16 # The list of valid query types 17 QUERY_TERMS = ( 18 'exact', 'iexact', 'contains', 'icontains', 19 'gt', 'gte', 'lt', 'lte', 'in', 20 'startswith', 'istartswith', 'endswith', 'iendswith', 21 'range', 'year', 'month', 'day', 'isnull', 22 ) 14 23 15 24 # Size of each "chunk" for get_iterator calls. … … 207 216 assert len(obj_list) == 1, "get() returned more than one %s -- it returned %s! Lookup parameters were %s" % (self.model._meta.object_name, len(obj_list), kwargs) 208 217 return obj_list[0] 209 218 210 219 def create(self, **kwargs): 211 220 """ … … 724 733 # a dummy name of None, which we will replace when 725 734 # we know which table column to grab as the primary key. 726 # 2) If there is only one part, assume it to be an __exact 735 # 2) If there is only one part, or the last part is not a query 736 # term, assume that the query is an __exact 727 737 clause = path.pop() 728 738 if clause == 'pk': 729 739 clause = 'exact' 730 740 path.append(None) 731 elif len(path) == 0 :741 elif len(path) == 0 or clause not in QUERY_TERMS: 732 742 path.append(clause) 733 743 clause = 'exact' … … 858 868 859 869 if path: 870 # There are elements left in the path. More joins are required. 860 871 if len(path) == 1 and path[0] in (new_opts.pk.name, None) \ 861 872 and clause in ('exact', 'isnull') and not join_required: 862 # If the last name query is for a key, and the search is for 863 # isnull/exact, then the current (for N-1) or intermediate 864 # (for N-N) table can be used for the search - no need to join an 865 # extra table just to check the primary key. 873 # If the next and final name query is for a primary key, 874 # and the search is for isnull/exact, then the current 875 # (for N-1) or intermediate (for N-N) table can be used 876 # for the search - no need to join an extra table just 877 # to check the primary key. 866 878 new_table = current_table 867 879 else: … … 889 901 params.extend(params2) 890 902 else: 891 # Evaluate clause on current table. 892 if name in (current_opts.pk.name, None) and clause in ('exact', 'isnull') and current_column: 893 # If this is an exact/isnull key search, and the last pass 894 # found/introduced a current/intermediate table that we can use to 895 # optimize the query, then use that column name. 903 # No elements left in path. Current element is the element on which 904 # the search is being performed. 905 906 if join_required: 907 # Last query term is a RelatedObject 908 if field.field.rel.multiple: 909 # RelatedObject is from a 1-N relation. 910 # Join is required; query operates on joined table. 911 column = new_opts.pk.name 912 joins[backend.quote_name(new_table)] = ( 913 backend.quote_name(new_opts.db_table), 914 "INNER JOIN", 915 "%s.%s = %s.%s" % 916 (backend.quote_name(current_table), 917 backend.quote_name(join_column), 918 backend.quote_name(new_table), 919 backend.quote_name(new_column)) 920 ) 921 current_table = new_table 922 else: 923 # RelatedObject is from a 1-1 relation, 924 # No need to join; get the pk value from the related object, 925 # and compare using that. 926 column = current_opts.pk.name 927 elif intermediate_table: 928 # Last query term is a related object from an N-N relation. 929 # Join from intermediate table is sufficient. 930 column = join_column 931 elif name == current_opts.pk.name and clause in ('exact', 'isnull') and current_column: 932 # Last query term is for a primary key. If previous iterations 933 # introduced a current/intermediate table that can be used to 934 # optimize the query, then use that table and column name. 896 935 column = current_column 897 936 else: 937 # Last query term was a normal field. 898 938 column = field.column 899 939 django/branches/multiple-db-support/django/db/models/related.py
r2809 r3258 71 71 return [None] * self.field.rel.num_in_admin 72 72 73 def get_db_prep_lookup(self, lookup_type, value): 74 # Defer to the actual field definition for db prep 75 return self.field.get_db_prep_lookup(lookup_type, value) 76 73 77 def editable_fields(self): 74 78 "Get the fields in this class that should be edited inline." django/branches/multiple-db-support/django/views/i18n.py
r2809 r3258 29 29 /* gettext identity library */ 30 30 31 function gettext(msgid) { 32 return msgid; 33 } 34 35 function ngettext(singular, plural, count) { 36 if (count == 1) { 37 return singular; 38 } else { 39 return plural; 40 } 41 } 42 43 function gettext_noop(msgid) { 44 return msgid; 45 } 31 function gettext(msgid) { return msgid; } 32 function ngettext(singular, plural, count) { return (count == 1) ? singular : plural; } 33 function gettext_noop(msgid) { return msgid; } 46 34 """ 47 35 … … 55 43 56 44 function gettext(msgid) { 57 var value = catalog[msgid]; 58 if (typeof(value) == 'undefined') { 59 return msgid; 60 } else { 61 if (typeof(value) == 'string') { 62 return value; 63 } else { 64 return value[0]; 65 } 66 } 45 var value = catalog[msgid]; 46 if (typeof(value) == 'undefined') { 47 return msgid; 48 } else { 49 return (typeof(value) == 'string') ? value : value[0]; 50 } 67 51 } 68 52 69 53 function ngettext(singular, plural, count) { 70 value = catalog[singular]; 71 if (typeof(value) == 'undefined') { 72 if (count == 1) { 73 return singular; 74 } else { 75 return plural; 76 } 77 } else { 78 return value[pluralidx(count)]; 79 } 54 value = catalog[singular]; 55 if (typeof(value) == 'undefined') { 56 return (count == 1) ? singular : plural; 57 } else { 58 return value[pluralidx(count)]; 59 } 80 60 } 81 61 82 function gettext_noop(msgid) { 83 return msgid; 84 } 62 function gettext_noop(msgid) { return msgid; } 85 63 """ 86 64 87 65 SimplePlural = """ 88 function pluralidx(count) { 89 if (count == 1) { 90 return 0; 91 } else { 92 return 1; 93 } 94 } 66 function pluralidx(count) { return (count == 1) ? 0 : 1; } 95 67 """ 96 68 97 69 InterPolate = r""" 98 70 function interpolate(fmt, obj, named) { 99 if (named) {100 return fmt.replace(/%\(\w+\)s/, function(match){return String(obj[match.slice(2,-2)])});101 } else {102 return fmt.replace(/%s/, function(match){return String(obj.shift())});103 }71 if (named) { 72 return fmt.replace(/%\(\w+\)s/, function(match){return String(obj[match.slice(2,-2)])}); 73 } else { 74 return fmt.replace(/%s/, function(match){return String(obj.shift())}); 75 } 104 76 } 105 77 """ 78 79 def null_javascript_catalog(request, domain=None, packages=None): 80 """ 81 Returns "identity" versions of the JavaScript i18n functions -- i.e., 82 versions that don't actually do anything. 83 """ 84 return http.HttpResponse(NullSource + InterPolate, 'text/javascript') 106 85 107 86 def javascript_catalog(request, domain='djangojs', packages=None): … … 192 171 src = ''.join(src) 193 172 return http.HttpResponse(src, 'text/javascript') 194 django/branches/multiple-db-support/docs/add_ons.txt
r3107 r3258 129 129 * ReST (ReStructured Text) 130 130 131 For documentation, read the source code in django/contrib/markup/templatetags/markup.py. 132 131 133 redirects 132 134 ========= django/branches/multiple-db-support/docs/authentication.txt
r3228 r3258 268 268 -------------------- 269 269 270 Depending on your task, you'll probably want to make sure to validate the 271 user's username and password before you log them in. The easiest way to do so 272 is to use the built-in ``authenticate`` and ``login`` functions from within a 273 view:: 270 Django provides two functions in ``django.contrib.auth``: ``authenticate()`` 271 and ``login()``. 272 273 To authenticate a given username and password, use ``authenticate()``. It 274 takes two keyword arguments, ``username`` and ``password``, and it returns 275 a ``User`` object if the password is valid for the given username. If the 276 password is invalid, ``authenticate()`` returns ``None``. Example:: 277 278 from django.contrib.auth import authenticate 279 user = authenticate(username='john', password='secret') 280 if user is not None: 281 print "You provided a correct username and password!" 282 else: 283 print "Your username and password were incorrect." 284 285 To log a user in, in a view, use ``login()``. It takes an ``HttpRequest`` 286 object and a ``User`` object. ``login()`` saves the user's ID in the session, 287 using Django's session framework, so, as mentioned above, you'll need to make 288 sure to have the session middleware installed. 289 290 This example shows how you might use both ``authenticate()`` and ``login()``:: 274 291 275 292 from django.contrib.auth import authenticate, login 276 username = request.POST['username'] 277 password = request.POST['password'] 278 user = authenticate(username=username, password=password) 279 if user is not None: 280 login(request, user) 281 282 ``authenticate`` checks the username and password. If they are valid it 283 returns a user object, otherwise it returns ``None``. ``login`` makes it so 284 your users don't have send a username and password for every request. Because 285 the ``login`` function uses sessions, you'll need to make sure you have 286 ``SessionMiddleware`` enabled. See the `session documentation`_ for 287 more information. 288 293 294 def my_view(request): 295 username = request.POST['username'] 296 password = request.POST['password'] 297 user = authenticate(username=username, password=password) 298 if user is not None: 299 login(request, user) 300 # Redirect to a success page. 301 else: 302 # Return an error message. 303 304 How to log a user out 305 --------------------- 306 307 To log out a user who has been logged in via ``django.contrib.auth.login()``, 308 use ``django.contrib.auth.logout()`` within your view. It takes an 309 ``HttpRequest`` object and has no return value. Example:: 310 311 from django.contrib.auth import logout 312 313 def logout_view(request): 314 logout(request) 315 # Redirect to a success page. 316 317 Note that ``logout()`` doesn't throw any errors if the user wasn't logged in. 289 318 290 319 Limiting access to logged-in users … … 569 598 For more, see the `RequestContext docs`_. 570 599 571 .. _RequestContext docs: http://www.djangoproject.com/documentation/templates_python/#subclassing-context- djangocontext600 .. _RequestContext docs: http://www.djangoproject.com/documentation/templates_python/#subclassing-context-requestcontext 572 601 573 602 Users … … 682 711 .. _session framework: http://www.djangoproject.com/documentation/sessions/ 683 712 684 Other Authentication Sources713 Other authentication sources 685 714 ============================ 686 715 687 Django supports other authentication sources as well. You can even use 688 multiple sources at the same time. 689 690 Using multiple backends 691 ----------------------- 692 693 The list of backends to use is controlled by the ``AUTHENTICATION_BACKENDS`` 694 setting. This should be a tuple of python path names. It defaults to 695 ``('django.contrib.auth.backends.ModelBackend',)``. To add additional backends 696 just add them to your settings.py file. Ordering matters, so if the same 697 username and password is valid in multiple backends, the first one in the 698 list will return a user object, and the remaining ones won't even get a chance. 716 The authentication that comes with Django is good enough for most common cases, 717 but you may have the need to hook into another authentication source -- that 718 is, another source of usernames and passwords or authentication methods. 719 720 For example, your company may already have an LDAP setup that stores a username 721 and password for every employee. It'd be a hassle for both the network 722 administrator and the users themselves if users had separate accounts in LDAP 723 and the Django-based applications. 724 725 So, to handle situations like this, the Django authentication system lets you 726 plug in another authentication sources. You can override Django's default 727 database-based scheme, or you can use the default system in tandem with other 728 systems. 729 730 Specifying authentication backends 731 ---------------------------------- 732 733 Behind the scenes, Django maintains a list of "authentication backends" that it 734 checks for authentication. When somebody calls 735 ``django.contrib.auth.authenticate()`` -- as described in "How to log a user in" 736 above -- Django tries authenticating across all of its authentication backends. 737 If the first authentication method fails, Django tries the second one, and so 738 on, until all backends have been attempted. 739 740 The list of authentication backends to use is specified in the 741 ``AUTHENTICATION_BACKENDS`` setting. This should be a tuple of Python path 742 names that point to Python classes that know how to authenticate. These classes 743 can be anywhere on your Python path. 744 745 By default, ``AUTHENTICATION_BACKENDS`` is set to:: 746 747 ('django.contrib.auth.backends.ModelBackend',) 748 749 That's the basic authentication scheme that checks the Django users database. 750 751 The order of ``AUTHENTICATION_BACKENDS`` matters, so if the same username and 752 password is valid in multiple backends, Django will stop processing at the 753 first positive match. 699 754 700 755 Writing an authentication backend 701 756 --------------------------------- 702 757 703 An authentication backend is a class that implements 2 methods: 704 ``get_user(id)`` and ``authenticate(**credentials)``. The ``get_user`` method 705 takes an id, which could be a username, and database id, whatever, and returns 706 a user object. The ``authenticate`` method takes credentials as keyword 707 arguments. Many times it will just look like this:: 758 An authentication backend is a class that implements two methods: 759 ``get_user(id)`` and ``authenticate(**credentials)``. 760 761 The ``get_user`` method takes an ``id`` -- which could be a username, database 762 ID or whatever -- and returns a ``User`` object. 763 764 The ``authenticate`` method takes credentials as keyword arguments. Most of 765 the time, it'll just look like this:: 708 766 709 767 class MyBackend: 710 768 def authenticate(username=None, password=None): 711 # check the username/password and return a user712 713 but it could also authenticate a tokenlike so::769 # Check the username/password and return a User. 770 771 But it could also authenticate a token, like so:: 714 772 715 773 class MyBackend: 716 774 def authenticate(token=None): 717 # check the token and return a user 718 719 Regardless, ``authenticate`` should check the credentials it gets, and if they 720 are valid, it should return a user object that matches those credentials. 721 722 The Django admin system is tightly coupled to the Django User object described 723 at the beginning of this document. For now, the best way to deal with this is 724 to create a Django User object for each user that exists for your backend 725 (i.e. in your LDAP directory, your external SQL database, etc.) You can either 726 write a script to do this in advance, or your ``authenticate`` method can do 727 it the first time a user logs in. Here's an example backend that 728 authenticates against a username and password variable defined in your 729 ``settings.py`` file and creates a Django user object the first time they 730 authenticate:: 775 # Check the token and return a User. 776 777 Either way, ``authenticate`` should check the credentials it gets, and it 778 should return a ``User`` object that matches those credentials, if the 779 credentials are valid. If they're not valid, it should return ``None``. 780 781 The Django admin system is tightly coupled to the Django ``User`` object 782 described at the beginning of this document. For now, the best way to deal with 783 this is to create a Django ``User`` object for each user that exists for your 784 backend (e.g., in your LDAP directory, your external SQL database, etc.) You 785 can either write a script to do this in advance, or your ``authenticate`` 786 method can do it the first time a user logs in. 787 788 Here's an example backend that authenticates against a username and password 789 variable defined in your ``settings.py`` file and creates a Django ``User`` 790 object the first time a user authenticates:: 731 791 732 792 from django.conf import settings … … 735 795 class SettingsBackend: 736 796 """ 737 Authenticate against vars in settings.py Use the login name, and a hash 738 of the password. For example: 797 Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD. 798 799 Use the login name, and a hash of the password. For example: 739 800 740 801 ADMIN_LOGIN = 'admin' … … 748 809 user = User.objects.get(username=username) 749 810 except User.DoesNotExist: 750 # Create a new user. Note that we can set password to anything 751 # as it won't be checked, the password from settings.py will. 811 # Create a new user. Note that we can set password 812 # to anything, because it won't be checked; the password 813 # from settings.py will. 752 814 user = User(username=username, password='get from settings.py') 753 815 user.is_staff = True django/branches/multiple-db-support/docs/faq.txt
r3227 r3258 412 412 ``{{ object.get_mug_shot_url }}``. 413 413 414 Databases and models 415 ==================== 416 417 How can I see the raw SQL queries Django is running? 418 ---------------------------------------------------- 419 420 Make sure your Django ``DEBUG`` setting is set to ``True``. Then, just do 421 this:: 422 423 >>> from django.db import connection 424 >>> connection.queries 425 [{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls', 426 'time': '0.002'}] 427 428 ``connection.queries`` is only available if ``DEBUG`` is ``True``. It's a list 429 of dictionaries in order of query execution. Each dictionary has the following:: 430 431 ``sql`` -- The raw SQL statement 432 ``time`` -- How long the statement took to execute, in seconds. 433 434 ``connection.queries`` includes all SQL statements -- INSERTs, UPDATES, 435 SELECTs, etc. Each time your app hits the database, the query will be recorded. 436 437 Can I use Django with a pre-existing database? 438 ---------------------------------------------- 439 440 Yes. See `Integrating with a legacy database`_. 441 442 .. _`Integrating with a legacy database`: http://www.djangoproject.com/documentation/legacy_databases/ 443 414 444 If I make changes to a model, how do I update the database? 415 445 ----------------------------------------------------------- … … 440 470 specify an object to edit or delete. 441 471 442 The database API 443 ================ 444 445 How can I see the raw SQL queries Django is running? 446 ---------------------------------------------------- 447 448 Make sure your Django ``DEBUG`` setting is set to ``True``. Then, just do 449 this:: 450 451 >>> from django.db import connection 452 >>> connection.queries 453 [{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls', 454 'time': '0.002'}] 455 456 ``connection.queries`` is only available if ``DEBUG`` is ``True``. It's a list 457 of dictionaries in order of query execution. Each dictionary has the following:: 458 459 ``sql`` -- The raw SQL statement 460 ``time`` -- How long the statement took to execute, in seconds. 461 462 ``connection.queries`` includes all SQL statements -- INSERTs, UPDATES, 463 SELECTs, etc. Each time your app hits the database, the query will be recorded. 464 465 Can I use Django with a pre-existing database? 466 ---------------------------------------------- 467 468 Yes. See `Integrating with a legacy database`_. 469 470 .. _`Integrating with a legacy database`: http://www.djangoproject.com/documentation/legacy_databases/ 472 How do I add database-specific options to my CREATE TABLE statements, such as specifying MyISAM as the table type? 473 ------------------------------------------------------------------------------------------------------------------ 474 475 We try to avoid adding special cases in the Django code to accomodate all the 476 database-specific options such as table type, etc. If you'd like to use any of 477 these options, create an `SQL initial data file`_ that contains ``ALTER TABLE`` 478 statements that do what you want to do. The initial data files are executed in 479 your database after the ``CREATE TABLE`` statements. 480 481 For example, if you're using MySQL and want your tables to use the MyISAM table 482 type, create an initial data file and put something like this in it:: 483 484 ALTER TABLE myapp_mytable ENGINE=MyISAM; 485 486 As explained in the `SQL initial data file`_ documentation, this SQL file can 487 contain arbitrary SQL, so you can make any sorts of changes you need to make. 488 489 .. _SQL initial data file: http://www.djangoproject.com/documentation/model_api/#providing-initial-sql-data 471 490 472 491 Why is Django leaking memory? django/branches/multiple-db-support/docs/i18n.txt
r3125 r3258 36 36 3. Activate the locale middleware in your Django settings. 37 37 38 39 38 .. admonition:: Behind the scenes 40 39 41 40 Django's translation machinery uses the standard ``gettext`` module that 42 41 comes with Python. 42 43 If you don't need internationalization 44 ====================================== 45 46 Django's internationalization hooks are on by default, and that means there's a 47 bit of i18n-related overhead in certain places of the framework. If you don't 48 use internationalization, you should take the two seconds to set 49 ``USE_I18N = False`` in your settings file. If ``USE_I18N`` is set to 50 ``False``, then Django will make some optimizations so as not to load the 51 internationalization machinery. 52 53 See the `documentation for USE_I18N`_. 54 55 .. _documentation for USE_I18N: http://www.djangoproject.com/documentation/settings/#use-i18n 43 56 44 57 How to specify translation strings django/branches/multiple-db-support/docs/serialization.txt
