rapidfields.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. # coding=utf-8
  2. from django.contrib.contenttypes.fields import GenericForeignKey
  3. from django.contrib.contenttypes.models import ContentType
  4. from rapid.rapidforms import RapidAlternativesField
  5. from django.db import models
  6. __author__ = 'marcos'
  7. """
  8. Model fields specific for Rapid Django.
  9. """
  10. class AlternativeData(GenericForeignKey):
  11. """
  12. A generic relation that Rapid will display as an inline form or a group of data at the
  13. edit and view actions.
  14. Create like a Django GenericForeignKey, but use an AlternativeDataTables instead of a
  15. ForeignKey to ContentTypes.
  16. """
  17. is_alternatives = True
  18. def __init__(self, *args, **kwargs):
  19. verbose_name = kwargs.get('verbose_name')
  20. if 'verbose_name' in kwargs:
  21. del(kwargs['verbose_name'])
  22. super(AlternativeData, self).__init__(*args, **kwargs)
  23. if verbose_name:
  24. self.verbose_name = verbose_name
  25. elif self.name:
  26. self.verbose_name = self.name.replace('_', ' ')
  27. def formfield(self, **kwargs):
  28. kwargs['form_class'] = RapidAlternativesField
  29. # noinspection PyUnresolvedReferences
  30. return super(GenericForeignKey, self).formfield(**kwargs)
  31. class AlternativeDataTables(models.ForeignKey):
  32. """
  33. Use an AlternativeDataTables model field on AlternativeData representations, instead of
  34. a ForeignKey with ContentTypes.
  35. """
  36. is_alternatives = True
  37. def __init__(self, alternatives=(), **kwargs):
  38. """
  39. Receives the same named parameters of a ForeignKey, but instead of a target table,
  40. receives a list of the tables that may keep the alternative data.
  41. :param alternatives: List of the tables that hold the alternative data.
  42. :param kwargs: Arguments to the ForeignKey, without a relationship target.
  43. """
  44. pks = []
  45. try:
  46. pks = [ContentType.objects.get_for_model(a).pk for a in alternatives]
  47. except RuntimeError:
  48. # Querying ContentType within a content type is an issue at migrations
  49. pass
  50. kwargs['limit_choices_to'] = {'pk__in': pks}
  51. kwargs['to'] = ContentType
  52. super(AlternativeDataTables, self).__init__(**kwargs)
  53. self.alternatives = alternatives