basefields.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. from django import forms
  2. from django.db.models import Q
  3. from django.utils.six import text_type
  4. __all__ = [
  5. 'ProfileField',
  6. 'TextProfileField',
  7. 'UrlProfileField',
  8. 'TextareaProfileField',
  9. 'ChoiceProfileField',
  10. ]
  11. class ProfileField(object):
  12. """
  13. Basic profile field
  14. """
  15. fieldname = None
  16. label = None
  17. help_text = None
  18. readonly = False
  19. def get_label(self, user):
  20. if not self.label:
  21. raise NotImplementedError(
  22. "profile field class has to define label "
  23. "attribute or get_label(user) method"
  24. )
  25. return self.label
  26. def get_help_text(self, user):
  27. return self.help_text
  28. def get_admin_field(self, user):
  29. return None
  30. def clean_admin_form(self, form, data):
  31. return data
  32. def admin_update_profile_fields(self, user, cleaned_data):
  33. if self.readonly:
  34. return
  35. user.profile_fields[self.fieldname] = cleaned_data.get(self.fieldname)
  36. def admin_search(self, criteria, queryset):
  37. return Q(**{
  38. 'profile_fields__{}__contains'.format(self.fieldname): criteria
  39. })
  40. class ChoiceProfileField(ProfileField):
  41. choices = None
  42. def get_choices(self, user=None):
  43. if not self.choices:
  44. raise NotImplementedError(
  45. "profile field ChoiceProfileField has to define "
  46. "choices attribute or get_choices(user) method"
  47. )
  48. return self.choices
  49. def get_admin_field(self, user):
  50. return forms.ChoiceField(
  51. label=self.get_label(user),
  52. help_text=self.get_help_text(user),
  53. initial=user.profile_fields.get(self.fieldname),
  54. choices=self.get_choices(user),
  55. disabled=self.readonly,
  56. required=False,
  57. )
  58. def admin_search(self, criteria, queryset):
  59. """custom search implementation for choice fields"""
  60. q_obj = Q(**{
  61. 'profile_fields__{}__contains'.format(self.fieldname): criteria
  62. })
  63. for key, choice in self.get_choices():
  64. if key and criteria.lower() in text_type(choice).lower():
  65. q_obj = q_obj | Q(**{
  66. 'profile_fields__{}'.format(self.fieldname): key
  67. })
  68. return q_obj
  69. class TextProfileField(ProfileField):
  70. def get_admin_field(self, user):
  71. return forms.CharField(
  72. label=self.get_label(user),
  73. help_text=self.get_help_text(user),
  74. initial=user.profile_fields.get(self.fieldname),
  75. max_length=250,
  76. disabled=self.readonly,
  77. required=False,
  78. )
  79. class TextareaProfileField(ProfileField):
  80. def get_admin_field(self, user):
  81. return forms.CharField(
  82. label=self.get_label(user),
  83. help_text=self.get_help_text(user),
  84. initial=user.profile_fields.get(self.fieldname),
  85. max_length=250,
  86. widget=forms.Textarea(
  87. attrs={'rows': 4},
  88. ),
  89. disabled=self.readonly,
  90. required=False,
  91. )
  92. class SlugProfileField(ProfileField):
  93. def get_admin_field(self, user):
  94. return forms.SlugField(
  95. label=self.get_label(user),
  96. help_text=self.get_help_text(user),
  97. initial=user.profile_fields.get(self.fieldname),
  98. max_length=250,
  99. disabled=self.readonly,
  100. required=False,
  101. )
  102. class UrlProfileField(ProfileField):
  103. def get_admin_field(self, user):
  104. return forms.URLField(
  105. label=self.get_label(user),
  106. help_text=self.get_help_text(user),
  107. initial=user.profile_fields.get(self.fieldname),
  108. max_length=250,
  109. disabled=self.readonly,
  110. required=False,
  111. )