Example #1
0
    def __init__(
        self,
        source_asset_or_uid: Union['kpi.models.Asset', str],
        filename: str,
        fields: list,
        asset: 'kpi.models.Asset',
        paired_data_uid: str = None,
    ):
        """
        Usually, this constructor should NOT be called directly except when
        creating a new paired data relationship. To retrieve existing pairings,
        use `PairedData.objects(asset)` instead.

        When the submission data from `source_asset_or_uid` is collected into
        a single XML file, it is attached to `asset` using `filename`, which
        the content of `asset` can then reference via `xml-external` (see
        https://xlsform.org/en/#external-xml-data). Specify a list of fields
        from the source asset to include using `fields`, or pass an empty list
        to include all fields.
        """
        try:
            self.source_uid = source_asset_or_uid.uid
        except AttributeError:
            self.source_uid = source_asset_or_uid
        self.asset = asset
        self.filename = filename
        self.fields = fields

        if not paired_data_uid:
            self.paired_data_uid = KpiUidField.generate_unique_id('pd')
        else:
            self.paired_data_uid = paired_data_uid

        self._asset_file = None
Example #2
0
    def save(self, **kwargs):

        # When PairedData objects are synchronize by back-end deployment class
        # (i.e.: `sync_media_files()` is triggered), the back-end deployment class
        # also updates the boolean `synced_with_backend`. We must handle this
        # over here before going further to avoid calling `Asset.save()`
        # which would call `sync_media_files()` again,
        # which would make us enter an infinite loop.
        try:
            update_fields = kwargs['update_fields']
        except KeyError:
            pass
        else:
            if 'synced_with_backend' in update_fields:
                AssetFile.objects.filter(uid=self.paired_data_uid).update(
                    synced_with_backend=self.synced_with_backend
                )
                return

        try:
            self.asset.paired_data[self.source_uid]['paired_data_uid']
            # self.paired_data_uid would have been set when `objects()`
            # calls the constructor
        except KeyError:
            self.paired_data_uid = KpiUidField.generate_unique_id('pd')

        self.asset.paired_data[self.source_uid] = {
            'fields': self.fields,
            'filename': self.filename,
            'paired_data_uid': self.paired_data_uid,
        }

        self.asset.save(
            update_fields=['paired_data'],
            adjust_content=False,
            create_version=False,
        )