def _translate(self, key, model, language_joins):
     ''' Translate a key on a model.
         language_joins must be a set that will be updated with required
         language joins for given key
     '''
     newkey = []
     for term in query_terms(model, key):
         if term.translated:
             newkey.append('%s__%s' % (term.model._meta.translations_accessor, term.term))
         else:
             newkey.append(term.term)
         if term.target is not None:
             taccessor = getattr(term.target._meta, 'translations_accessor', None)
             if taccessor is not None:
                 language_joins.add('__'.join(newkey + [taccessor, 'language_code']))
     return '__'.join(newkey)
Exemple #2
0
    def _add_select_related(self):
        fields = self._raw_select_related
        related_queries = []
        if not self._skip_master_select and getattr(self, '_fields',
                                                    None) is None:
            related_queries.append('master')

        for query_key in fields:
            newbits = []
            for term in query_terms(self.shared_model, query_key):

                # Translate term
                if term.depth == 0 and not term.translated:
                    # on initial depth we must key to shared model
                    newbits.append('master__%s' % term.term)
                elif term.depth > 0 and term.translated:
                    # on deeper levels we must key to translations model
                    # this will work because translations will be seen as _unique
                    # at query time
                    newbits.append('%s__%s' % ('_hvad_query', term.term))
                else:
                    newbits.append(term.term)

                # Some helpful messages for common mistakes
                if term.many:
                    raise FieldError(
                        'Cannot select_related: %s can be multiple objects. '
                        'Use prefetch_related instead.' % query_key)
                if term.target is None:
                    raise FieldError(
                        'Cannot select_related: %s is a regular field' %
                        query_key)
                if term.field.many_to_many or term.field.one_to_many:
                    raise FieldError(
                        'Cannot select_related: %s can be multiple objects. '
                        'Use prefetch_related instead.' % query_key)
                # If target is a translated model, select its translations
                if hasattr(term.target._meta, 'translations_model'):
                    # Add the model
                    target_query = '__'.join(newbits)
                    related_queries.append('%s__%s' %
                                           (target_query, '_hvad_query'))

            related_queries.append('__'.join(newbits))

        # Apply results to query
        self.query.add_select_related(related_queries)
Exemple #3
0
 def _translate(self, key, model, language_joins):
     ''' Translate a key on a model.
         language_joins must be a set that will be updated with required
         language joins for given key
     '''
     newkey = []
     for term in query_terms(model, key):
         if term.translated:
             newkey.append(
                 '%s__%s' %
                 (term.model._meta.translations_accessor, term.term))
         else:
             newkey.append(term.term)
         if term.target is not None:
             taccessor = getattr(term.target._meta, 'translations_accessor',
                                 None)
             if taccessor is not None:
                 language_joins.add('__'.join(newkey +
                                              [taccessor, 'language_code']))
     return '__'.join(newkey)
    def _add_select_related(self, language_code):
        fields = self._raw_select_related
        related_queries = []
        language_filters = []
        force_unique_fields = []
        if not self._skip_master_select and getattr(self, '_fields', None) is None:
            related_queries.append('master')

        for query_key in fields:
            newbits = []
            for term in query_terms(self.shared_model, query_key):

                # Translate term
                if term.depth == 0 and not term.translated:
                    # on initial depth we must key to shared model
                    newbits.append('master__%s' % term.term)
                elif term.depth > 0 and term.translated:
                    # on deeper levels we must key to translations model
                    # this will work because translations will be seen as _unique
                    # at query time
                    newbits.append('%s__%s' % (term.model._meta.translations_accessor, term.term))
                else:
                    newbits.append(term.term)

                # Some helpful messages for common mistakes
                if term.many:
                    raise FieldError('Cannot select_related: %s can be multiple objects. '
                                     'Use prefetch_related instead.' % query_key)
                if term.target is None:
                    raise FieldError('Cannot select_related: %s is a regular field' % query_key)
                if hasattr(term.field.rel, 'through'):
                    raise FieldError('Cannot select_related: %s can be multiple objects. '
                                     'Use prefetch_related instead.' % query_key)

                # If target is a translated model, select its translations
                target_translations = getattr(term.target._meta, 'translations_accessor', None)
                if target_translations is not None:
                    # Add the model
                    target_query = '__'.join(newbits)
                    related_queries.append('%s__%s' % (target_query, target_translations))

                    # Add a language filter for the translation
                    language_filters.append('%s__%s__language_code' % (
                        target_query,
                        target_translations,
                    ))

                    # Remember to mark the field unique so JOIN is generated
                    # and row decoder gets cached items
                    if django.VERSION >= (1, 9):
                        target_transfield = getattr(term.target, target_translations).field
                    else:
                        target_transfield = getattr(term.target, target_translations).related.field
                    force_unique_fields.append(target_transfield)

            related_queries.append('__'.join(newbits))

        # Apply results to query
        self.query.add_select_related(related_queries)
        for language_filter in language_filters:
            self.query.add_q(Q(**{language_filter: language_code}) |
                             Q(**{language_filter: None}))

        self._forced_unique_fields = force_unique_fields
Exemple #5
0
    def _add_select_related(self, language_code):
        fields = self._raw_select_related
        related_queries = []
        language_filters = []
        force_unique_fields = []
        if not self._skip_master_select and getattr(self, '_fields',
                                                    None) is None:
            related_queries.append('master')

        for query_key in fields:
            newbits = []
            for term in query_terms(self.shared_model, query_key):

                # Translate term
                if term.depth == 0 and not term.translated:
                    # on initial depth we must key to shared model
                    newbits.append('master__%s' % term.term)
                elif term.depth > 0 and term.translated:
                    # on deeper levels we must key to translations model
                    # this will work because translations will be seen as _unique
                    # at query time
                    newbits.append(
                        '%s__%s' %
                        (term.model._meta.translations_accessor, term.term))
                else:
                    newbits.append(term.term)

                # Some helpful messages for common mistakes
                if term.many:
                    raise FieldError(
                        'Cannot select_related: %s can be multiple objects. '
                        'Use prefetch_related instead.' % query_key)
                if term.target is None:
                    raise FieldError(
                        'Cannot select_related: %s is a regular field' %
                        query_key)
                if hasattr(term.field.rel, 'through'):
                    raise FieldError(
                        'Cannot select_related: %s can be multiple objects. '
                        'Use prefetch_related instead.' % query_key)

                # If target is a translated model, select its translations
                target_translations = getattr(term.target._meta,
                                              'translations_accessor', None)
                if target_translations is not None:
                    # Add the model
                    target_query = '__'.join(newbits)
                    related_queries.append('%s__%s' %
                                           (target_query, target_translations))

                    # Add a language filter for the translation
                    language_filters.append('%s__%s__language_code' % (
                        target_query,
                        target_translations,
                    ))

                    # Remember to mark the field unique so JOIN is generated
                    # and row decoder gets cached items
                    if django.VERSION >= (1, 9):
                        target_transfield = getattr(term.target,
                                                    target_translations).field
                    else:
                        target_transfield = getattr(
                            term.target, target_translations).related.field
                    force_unique_fields.append(target_transfield)

            related_queries.append('__'.join(newbits))

        # Apply results to query
        self.query.add_select_related(related_queries)
        for language_filter in language_filters:
            self.query.add_q(
                Q(**{language_filter: language_code})
                | Q(**{language_filter: None}))

        self._forced_unique_fields = force_unique_fields