12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- # coding=utf-8
- from __future__ import absolute_import
- from __future__ import division
- from __future__ import print_function
- from __future__ import unicode_literals
- from django.contrib.contenttypes.fields import GenericForeignKey
- from django.contrib.contenttypes.models import ContentType
- from rapid.rapidforms import RapidAlternativesField
- from django.db import models
- __author__ = 'marcos'
- """
- Model fields specific for Rapid Django.
- """
- class AlternativeData(GenericForeignKey):
- """
- A generic relation that Rapid will display as an inline form or a group of data at the
- edit and view actions.
- Create like a Django GenericForeignKey, but use an AlternativeDataTables instead of a
- ForeignKey to ContentTypes.
- That is, a model becomes something like this:
- class MyModel(models.Model):
- alt_data_type = rapidfields.AlternativeDataTables((Model1, Model2))
- alt_data_id = models.PositiveIntegerField()
- alt_data = rapidfields.AlternativeData('alt_data_type', 'alt_data_id', verbose_name='fill either a model1 or
- a model2 object')
- In forms, Rapid will display a select widget with the options "model1" and "model2",
- and show the appropriate form after selected.
- """
- is_rapid_alternatives = True
- def __init__(self, *args, **kwargs):
- verbose_name = kwargs.get('verbose_name')
- if 'verbose_name' in kwargs:
- del(kwargs['verbose_name'])
- super(AlternativeData, self).__init__(*args, **kwargs)
- if verbose_name:
- self.verbose_name = verbose_name
- elif self.name:
- self.verbose_name = self.name.replace('_', ' ')
- def formfield(self, **kwargs):
- kwargs['form_class'] = RapidAlternativesField
- # noinspection PyUnresolvedReferences
- return super(GenericForeignKey, self).formfield(**kwargs)
- class AlternativeDataTables(models.ForeignKey):
- """
- Use an AlternativeDataTables model field on AlternativeData representations, instead of
- a ForeignKey with ContentTypes.
- """
- is_rapid_alternatives = True
- def __init__(self, alternatives=(), **kwargs):
- """
- Receives the same named parameters of a ForeignKey, but instead of a target table,
- receives a list of the tables that may keep the alternative data.
- :param alternatives: List of the tables that hold the alternative data.
- :param kwargs: Arguments to the ForeignKey, without a relationship target.
- """
- pks = []
- try:
- pks = [ContentType.objects.get_for_model(a).pk for a in alternatives]
- except RuntimeError:
- # Querying ContentType within a content type is an issue at migrations
- pass
- kwargs['limit_choices_to'] = {'pk__in': pks}
- kwargs['to'] = ContentType
- super(AlternativeDataTables, self).__init__(**kwargs)
- self.alternatives = alternatives
|