How to get a model that allows "bidirectionality"?

Hi guys,
I have started looking into Django more closely, recently and thus started to create a vocabulary learning app.
Right now, the admin (me :-D) can add a Word via the admin-backend that consists of language, word translation, Words

Here I can also either create languages and words independently or via Word translations, as you can see in the code below.

Now, I have the result looking somewhat like this:

<QuerySet [<WordTranslation: 3 Morgen, Bahasa Indonesia: Pagi >]>

3: ID, Morgen (german word), Bahasa Indonesia (language to learn): Pagi (word meaning in said language).

This is my models.py:

class Language(models.Model):
    name = models.CharField(max_length=20)
    def __str__(self):
        return self.name


class Word(models.Model):
    word = models.CharField(max_length=50)

    def __str__(self):
        return self.word


class WordTranslation(models.Model):
    vocabulary = models.ForeignKey(Word, on_delete=models.CASCADE)
    language = models.ForeignKey(Language, on_delete=models.CASCADE)
    translation = models.CharField(max_length=50)

    def __str__(self):
        return f' {self.pk} {self.vocabulary}, {self.language}: {self.translation} '

    class Meta:
        unique_together = ['vocabulary', 'language', 'translation']

I want to be able to switch between languages easily, but since I’d have to setup every word translation as an extra word for now, I am stuck with adding every word twice but with the translation and vocabulary changed…
i.e. adding a word in both languages and just switch vocabulary and translation around. This seems inefficient.

I want to avoid hardcoding languages, thus having translation_id, and translation_de is not really a solution.

Is there an easy way to modify the model to allow me to easily switch between languages:

<h1> What does <span style="color:red;">{{ vocabulary }}</span> mean in <span style="color:green;">{{ language }}?</span></h1>

(vocabulary outputs Morgen and language gives Bahasa Indonesia)
I fear this might get out of hand, as I don’t have much experience with modelling dbs, other than textual data (TEI) or simpler entries (calendar events, blog entries, etc.).

Any hints or would this be the best solution for that?
It should, ideally, be expandable to allow n languages, so that I can easily add “support for another language” (i.e. add a language in the admin-site and then populate the model accordingly)

For now I somehow have a json-file (or a dict) that looks somewhat like this in mind:

{pk:pk, 
concept:english_version, 
dt:german_version, 
indo:indonesian_version
}

Now the annoying thing that I am thinking off:
How about an easy way to add support for more languages? If let’s say people want to learn Italian ad I decide to add a column italian. How do I get existing entries to automatically update to have

 {pk:pk, 
concept:english_version, 
dt:german_version, 
indo:indonesian_version
it: ""
}

so that I can add the meaning of the word in the admin backend, so that in the following screenshot there is no Language to, but just german_version, indo_version, ital_version and the admin has to enter all data accordingly.

(I know the last step is not essential for now)

I am not sure whether I actually need all my models, thinking about it now, I think I could get away with
WordPhrase and Language, but I am probably oversimplifying things here.

Can anyone help with that?

This is an interesting issue.

I can think of two different ways to approach this, and the selection between them depends upon a couple of things.

  1. Is there a “base language” for which all words would be defined? Or is it a case where you want words to exist independent of any one language?

  2. Is there additional information associated with each word (such as a definition or usage example or other context-sensitive information)?

  3. Would that additional information exist in each language or in the “base language” as identified above?

If it’s a case where there is no base language, then my initial thought would be to have each “word” assigned an arbitrary id, and each of the languages referencing that id.

This creates a schema that might look something like this:

class AbstractWord(Model):
    word_id = BigAutoField(primary_key=True)

class Language(Model):
    name = CharField(...)

class Word(Model):
    word = ForeignKey(AbstractWord, ...)
    language = ForeignKey(Language, ...)
    text = CharField(...)
    definition = CharField(...)

This would let you dynamically add languages and then populate the words for that language, while being related to the same concept in other languages.

What we have effectively done here is create a many-to-many relationship between “AbstractWord” and “Language” with “Word” being the through-table.

It would also allow you to define multiple words that all have the same meaning. (Depending upon what you’re doing with this, that may make other things more difficult - but that’s up to you.)

However, this is one of those situations that really should be addressed within the specific context of the application being built. I wouldn’t necessarily say that this is the “best” or most optimal way for you to approach this without having a more complete understanding of the application being built and of all the functionality needed.

Good morning :slight_smile:

and thank you for your thoughts, I’ll try to answer as good as I can.
As it seems I did not think enough about the word model, which is funny since I studied linguistics :smiley: :smiley:

I think it’s easiest to have a “lingua franca” a common ground, I would not decide for Latin or French, but having an abstract word, probably English, since I just assume (at least for now) that all users will speak English.

should be, could be, maybe at a later stage. :smiley:

this is a difficult question. First, it should be there in the base language and later on, the info could be added.

I just tried your models and it seems good, however, I had sth. different in mind:

I wanted a field “Text” for every language instead it being individual word entries. Does this make sense?
So I have languages, let’s say Bahasa Indonesia and German and what’s “Text” in the screenshot I get
“Bahasa Indonesia” and for German it’s basically the same and for every language that I add the field appears accordingly.
Does this make sense (to you and from a model-perspective) and is this even possible?
Is this still a “I have a Model and need help with it”-question? :smiley:

As you can probably tell, my experience with models stops rather early on. I mainly deal with TEI-documents which is a rather constrained model :smiley:

Thank you, again, for your time and effort, I learned a lot from reading your reply :slight_smile:

That’s what my model provides.

Let’s look at an example.

With three words, you might have data in your tables that look like this:

AbstractWord
word_id
   1
   2
   3

Language
id     name
 1       English
 2       French
 3       Spanish

Word
id   word   language   text
 1     1       1         car
 2     1       2         voiture
 3     1       3         coche
 4     2       1         boat
 5     2       2         bateau
 6     3       1         airplane
 7     3       3         avion

(Disclaimer: I’m relying upon Google translate for this, I don’t know either Spanish or French)

Note that there doesn’t necessarily need to be a lingua franca here, but your application can enforce that from an implementation perspective. Also note that not every language needs to have every word defined.

Then, if you want, you can add the native language additional data for any word, since those would be fields in the Word model.

At first, I wasn’t sure that I fully understand your response, then I looked closely and now I somehow understand what you’re talking about and I also understand that I am talking about something else … :smiley:

I think I want each word-element to show all languages and translations in one window.
where it says “Language → German” in the Screenshot and “Text → Morgen”, I’d like to have the “Language → Bahasa Indonesia” followed by “Text → Pagi” instead of it being a different object it should be in one object.

Does that make sense and is it possible? :smiley:

image

Thank you for your patience and help!

small edit:
my starting model for words was:

class Word(models.Model):
    word_en = CharField(...)
    word_dt = CharField(...)
    word_indo = CharField(...)

Where I could get every word-translation in one view in the admin-view, maybe looking at that provides a better idea of what I want to achieve :smiley:

The admin is not going to be your best tool for this.

Please read the first two paragraphs at The Django admin site | Django documentation | Django

Now, having said that, you can get close to this by using AbstractWord as the base model that you browse in the admin and use InlineModelAdmin objects to display all related words on that page.

But what you really don’t want to do is design your models around the admin. The admin is a tool - one of many you will be using, but it’s not the entire site. Model your data first, then pick the appropriate tools to work with that data.

Your answers are super helpful. not only are you saying why or in this case why not, you are also providing additional info and give an option that might help! Thanks for that!

I think the data-model should contain a “base word” and different languages should be added. I think that somehow having it in json (or XML, I deal with this every day) might be a good idea.

I think for now, I will go with your suggestion of models and see how far I can go without regretting any decision … At the moment I feel I am not making any progress due to the modelling question, which is important but not helpful with learning the ins and outs of django itself. It is a learning-project after all …
(biggest learning so far: I need to get better at data modelling, thanks for the insight!)

Unfortunately right now, I am suffering from migraines due to sudden and heavy weather changes, so I haven’t looked into my app since my last reply, but I will do that later!
I will try it out once my head allows for longer periods staring at screens and I will probably run into issues as well, upon which I will bug people on her again about it…

I will report back whether it works as intended or not!

That’s fine - you can certainly add data fields to the AbstractWord model.

I think it’s a horrible idea. JSON and XML are data serialization representations. They’re excellent for transmitting information between systems.

They’re lousy for actual data storage.

And with any luck, we’ll still be here to help. Good luck! (And I hope you get to feeling better.)