3

I've got a model named String that looks something like this:

class String(models.Model):
    text = models.TextField()
    language = models.ForeignKey(Language, default=get_english)
    original_string = models.ForeignKey('self', null=True, blank=True)

The default language for the strings is English, then, in the same table on the database, I have the translated strings with different languages, each one pointing to the corresponding string in English through original_string.

What I need is to retrieve the strings in English that DON'T have associated strings in another language, i.e., that don't have a translation.

Right now I'm iterating over all string in English and appending the ones I need to a list, like:

translatable_strings = String.objects.filter(language__name="English")

strings = []

for string in translatable_strings:
    if not String.objects.filter(language=translator_lang,
                                 original_string=string).exists():
        strings.append(string)

But I think that's a pretty nasty piece of code. Isn't there a way to make this in a single query?

Aylen
  • 3,524
  • 26
  • 36

2 Answers2

4

First condition: language is english

Second condition: not exists another string that references it.

String.objects.filter( language = 'english', 
                       string__original_string__isnull = True )

A foreignkey backward reference is needed.

Community
  • 1
  • 1
dani herrera
  • 48,760
  • 8
  • 117
  • 177
  • "Foreignkey backward reference" sounds exactly like what I'm looking for. I'll try that now. – Aylen Dec 22 '12 at 20:04
  • @Filly, perhaps it is enough with `string__isnull = True` try it and come back with news. – dani herrera Dec 22 '12 at 20:25
  • @danihp you said `English strings don't references another model, is the other languages who references english string. Is not?` If other language reference english string then it should have reference in original_string. How my query will fail? – Aamir Rind Dec 22 '12 at 20:42
  • Indeed, your answer was very helpful! What I forgot to say in my question was that I need to specify in what language the string in English has not an string pointing to it (i.e. the string has not a translation in X language), so I ended up writing the query like: `String.objects.filter(language__name="English").exclude(string__language=translator.language)` and it works amazingly. Thank you VERY much for your help! – Aylen Dec 23 '12 at 20:18
1

Try this

String.objects.filter(language__name="English", original_string__isnull=True)
Aamir Rind
  • 38,793
  • 23
  • 126
  • 164
  • 1
    English strings don't references another model, is the other languages who references english string. Is not? – dani herrera Dec 22 '12 at 19:47
  • Wouldn't this retrieve all strings in English? All strings in English have original_string=null, because they don't have a default string to point to (they're the default). I need to retrieve strings in English that are not the original_string of another string in a given language. – Aylen Dec 22 '12 at 19:48
  • @AamirAdnan I found danihp's solution to suit my problem, but your answer using Q objects was helpful for another piece of code I needed to write. Thank you very much! – Aylen Dec 23 '12 at 20:24