Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

compat.py 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. from django.utils import six
  2. from django.conf import settings
  3. from django.contrib.auth import get_user_model as django_get_user_model
  4. from django.contrib.auth.models import User
  5. from django.core.exceptions import ImproperlyConfigured
  6. # A setting that can be used in foreign key declarations
  7. AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
  8. # Two additional settings that are useful in South migrations when
  9. # specifying the user model in the FakeORM
  10. try:
  11. AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME = AUTH_USER_MODEL.rsplit('.', 1)
  12. except ValueError:
  13. raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form"
  14. " 'app_label.model_name'")
  15. def get_user_model():
  16. """
  17. Return the User model. Doesn't require the app cache to be fully
  18. initialised.
  19. This used to live in compat to support both Django 1.4's fixed User model
  20. and custom user models introduced thereafter.
  21. Support for Django 1.4 has since been dropped in Oscar, but our
  22. get_user_model remains because code relies on us annotating the _meta class
  23. with the additional fields, and other code might rely on it as well.
  24. """
  25. # As Oscar uses get_user_model all over the codebase, we need to be able to
  26. # fetch the model without Django checking if the app cache is ready.
  27. # Pre-Django 1.7, that check doesn't happen anyway and we can just use
  28. # get_user_model. In Django 1.7, we revert to get_registered_model, which
  29. # is the last remaining call to get into the model registry without
  30. # Django enforcing that it's fully populated.
  31. try:
  32. from django.apps import apps
  33. except ImportError:
  34. # Django <1.7
  35. model = django_get_user_model()
  36. else:
  37. # Django >=1.7
  38. model = apps.get_registered_model(
  39. AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME)
  40. # Test if user model has any custom fields and add attributes to the _meta
  41. # class
  42. core_fields = set([f.name for f in User._meta.fields])
  43. model_fields = set([f.name for f in model._meta.fields])
  44. new_fields = model_fields.difference(core_fields)
  45. model._meta.has_additional_fields = len(new_fields) > 0
  46. model._meta.additional_fields = new_fields
  47. return model
  48. def existing_user_fields(fields):
  49. """
  50. Starting with Django 1.6, the User model can be overridden and it is no
  51. longer safe to assume the User model has certain fields. This helper
  52. function assists in writing portable forms Meta.fields definitions
  53. when those contain fields on the User model
  54. Usage:
  55. class UserForm(forms.Form):
  56. ...
  57. class Meta:
  58. # won't break if first_name is not defined on User model
  59. fields = existing_user_fields(['first_name', 'last_name'])
  60. """
  61. user_fields = get_user_model()._meta.fields
  62. user_field_names = [field.name for field in user_fields]
  63. return list(set(fields) & set(user_field_names))
  64. # Python3 compatibility layer
  65. # Make backwards-compatible atomic decorator available
  66. try:
  67. from django.db.transaction import atomic as atomic_compat
  68. except ImportError:
  69. from django.db.transaction import commit_on_success as atomic_compat
  70. atomic_compat = atomic_compat
  71. """
  72. Unicode compatible wrapper for CSV reader and writer that abstracts away
  73. differences between Python 2 and 3. A package like unicodecsv would be
  74. preferable, but it's not Python 3 compatible yet.
  75. Code from http://python3porting.com/problems.html
  76. Changes:
  77. - Classes renamed to include CSV.
  78. - Unused 'codecs' import is dropped.
  79. - Added possibility to specify an open file to the writer to send as response
  80. of a view
  81. """
  82. import sys
  83. import csv
  84. PY3 = sys.version > '3'
  85. class UnicodeCSVReader:
  86. def __init__(self, filename, dialect=csv.excel,
  87. encoding="utf-8", **kw):
  88. self.filename = filename
  89. self.dialect = dialect
  90. self.encoding = encoding
  91. self.kw = kw
  92. def __enter__(self):
  93. if PY3:
  94. self.f = open(self.filename, 'rt',
  95. encoding=self.encoding, newline='')
  96. else:
  97. self.f = open(self.filename, 'rbU')
  98. self.reader = csv.reader(self.f, dialect=self.dialect,
  99. **self.kw)
  100. return self
  101. def __exit__(self, type, value, traceback):
  102. self.f.close()
  103. def next(self):
  104. row = next(self.reader)
  105. if PY3:
  106. return row
  107. return [s.decode("utf-8") for s in row]
  108. __next__ = next
  109. def __iter__(self):
  110. return self
  111. class UnicodeCSVWriter:
  112. """
  113. Python 2 and 3 compatible CSV writer. Supports two modes:
  114. * Writing to an open file or file-like object:
  115. writer = UnicodeCSVWriter(open_file=your_file)
  116. ...
  117. your_file.close()
  118. * Writing to a new file:
  119. with UnicodeCSVWriter(filename=filename) as writer:
  120. ...
  121. """
  122. def __init__(self, filename=None, open_file=None, dialect=csv.excel,
  123. encoding="utf-8", **kw):
  124. if filename is open_file is None:
  125. raise ImproperlyConfigured(
  126. "You need to specify either a filename or an open file")
  127. self.filename = filename
  128. self.f = open_file
  129. self.dialect = dialect
  130. self.encoding = encoding
  131. self.kw = kw
  132. self.writer = None
  133. def __enter__(self):
  134. assert self.filename is not None
  135. if PY3:
  136. self.f = open(self.filename, 'wt',
  137. encoding=self.encoding, newline='')
  138. else:
  139. self.f = open(self.filename, 'wb')
  140. def __exit__(self, type, value, traceback):
  141. assert self.filename is not None
  142. if self.filename is not None:
  143. self.f.close()
  144. def writerow(self, row):
  145. if self.writer is None:
  146. self.writer = csv.writer(self.f, dialect=self.dialect, **self.kw)
  147. if not PY3:
  148. row = [six.text_type(s).encode(self.encoding) for s in row]
  149. self.writer.writerow(list(row))
  150. def writerows(self, rows):
  151. for row in rows:
  152. self.writerow(row)