bruvellu / cifonauta

Marine biology image database by CEBIMar/USP
http://cifonauta.cebimar.usp.br
GNU General Public License v3.0
21 stars 5 forks source link

ModifiedMedia is a duplicated model #236

Open bruvellu opened 12 months ago

bruvellu commented 12 months ago

The ModifiedMedia model stores the modified metadata of a particular file. But currently, it's a semi-duplicate of Media including the fields. This is not ideal to maintain, specially if the fields change.

One alternative solution is Media to have a modified_media field pointing to a temporary Media instance. Whenever metadata is to be edited, the media is duplicated (new entry/id) and linked as modified_media. Once the changes have been accepted, the duplicated media instance can be deleted. In this way, modified_media will always have the same fields as Media (because it is a Media instance). Based on the documentation, the recommended way of doing this is using a self-referenced ForeignKey:

class Media(models.Model):
    modified_media = models.ForeignKey('self', on_delete=models.CASCADE, verbose_name=_('mídia modificada'), help_text=_('Mídia temporária guardando os metadados modificados.'), related_name='modified_media'))

However, another solution is using Multi table inheritance. The advantage here is that the modified media will be on a separate table. They will not show up when we perform a regular query on Media (we don't want duplicated media showing up). This would look like this:

class Media(models.Model):
    (...)
class ModifiedMedia(Media):
    original_media = models.ForeignKey('Media', on_delete=models.SET_NULL, verbose_name=_('mídia original'), help_text=_('Mídia original com metadados antes das modificações.'), related_name='modified_media'))
bruvellu commented 11 months ago

Instead of manually passing all the fields to create a new ModifiedMedia object, there are ways to create a copy of a model instance: https://docs.djangoproject.com/en/4.2/topics/db/queries/#copying-model-instances (still a bit involved).

See also: