Tag
All primary entities but the genre and URL (i.e. area, artist, event, instrument, label, place, recording, release, release group, series and work) have *_tag and *_tag_raw tables, with the same structure.
These tables contain two foreign keys, linked to the associated entity and to the tag table.
The *_tag_raw tables contain a foreign key, editor, which specifies who added the tag, while the *_tag tables instead contain a count of how many times a tag is applied to a particular entity, and a last_updated timestamp.
For privacy reasons, the *_tag_raw tables aren’t included in the database dumps. The tag table contains the actual names of the tags, and a ref_count indicating how often the tag has been used.
Model Documentation
- class django_musicbrainz_connector.models.tag.Tag(*args, **kwargs)[source]
PostgreSQL Definition
The
tagtable is defined in the MusicBrainz Server as:CREATE TABLE tag ( -- replicate (verbose) id SERIAL, name VARCHAR(255) NOT NULL, ref_count INTEGER NOT NULL DEFAULT 0 );
- class django_musicbrainz_connector.models.base_tag_model.TagModel(*args, **kwargs)[source]
PostgreSQL Definition
The
M_tagtable is defined in the MusicBrainz Server as:CREATE TABLE M_tag ( -- replicate (verbose) M INTEGER NOT NULL, -- PK, references M.id tag INTEGER NOT NULL, -- PK, references tag.id count INTEGER NOT NULL, last_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW() );
Model Source
Tag
class Tag(models.Model):
"""
PostgreSQL Definition
---------------------
The :code:`tag` table is defined in the MusicBrainz Server as:
.. code-block:: sql
CREATE TABLE tag ( -- replicate (verbose)
id SERIAL,
name VARCHAR(255) NOT NULL,
ref_count INTEGER NOT NULL DEFAULT 0
);
"""
id = models.IntegerField("ID", primary_key=True, db_column="id")
name = models.CharField(max_length=255, db_column="name")
ref_count = models.IntegerField("Ref Count", db_column="ref_count")
def __str__(self) -> str:
return self.name
class Meta:
managed = False
db_table = "tag"
verbose_name_plural = "Tags"
ordering = ["name"]
TagModel
class TagModel(models.Model):
"""
PostgreSQL Definition
---------------------
The :code:`M_tag` table is defined in the MusicBrainz Server as:
.. code-block:: sql
CREATE TABLE M_tag ( -- replicate (verbose)
M INTEGER NOT NULL, -- PK, references M.id
tag INTEGER NOT NULL, -- PK, references tag.id
count INTEGER NOT NULL,
last_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
"""
tag = models.ForeignKey("Tag", db_column="tag", on_delete=models.PROTECT)
count = models.IntegerField("Count", db_column="count")
last_updated = models.DateTimeField(db_column="last_updated")
class Meta:
abstract = True
Dynamic model creation for tagged table
from django.apps import AppConfig
from django.db import models
from django_musicbrainz_connector.utils import clone_field
class DjangoMusicbrainzConnectorConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "django_musicbrainz_connector"
def ready(self):
# Also available, but not in django_musicbrainz_connector yet: Event, Instrument, Label, Place, Series
import django_musicbrainz_connector.models
from django_musicbrainz_connector.models import Area, Artist, Recording, Release, ReleaseGroup, Tag, Work
from django_musicbrainz_connector.models.base_tag_model import TagModel
for model_class in [Area, Artist, Recording, Release, ReleaseGroup, Work]:
# Creation of the <Model>Tag model, based on the list
class_name = f"{model_class.__qualname__}Tag"
class_relation_name = model_class._meta.db_table
# Create the Meta class (not metaclass) for the <Model>Tag class
meta_class = type(
"Meta",
(),
{
"managed": False,
"db_table": f"{class_relation_name}_tag",
"verbose_name_plural": f"{model_class.__qualname__} Tags",
"ordering": ["pk"],
},
)
tag_field = TagModel._meta.get_field("tag")
model_tag_class = type(
class_name,
(TagModel,),
{
"__module__": "django_musicbrainz_connector.models",
# All `M_tag` table have composite primary key with the `M` table and the tag one
"pk": models.CompositePrimaryKey(class_relation_name, "tag"),
class_relation_name: models.ForeignKey(
model_class,
on_delete=models.PROTECT,
db_column=class_relation_name,
# Access through `M.m_tag_m2m.all()`
related_name=f"{class_relation_name}_tag_m2m",
),
# Access through `tag.m_tag_m2m.all()`
"tag": clone_field(tag_field, related_name=f"{class_relation_name}_tag_m2m"),
"Meta": meta_class,
},
)
# Set into the module so it can be auto imported
# with `from django_musicbrainz_connector.models import ModelTag`
setattr(django_musicbrainz_connector.models, class_name, model_tag_class)
# Add the m2m relation between Model <> Tag, so we can use:
# - the convenient `tag.models.all()`
# - and `model.tags.all()`
# Without the necessity of manually navigating the through-table,
# those options remain accessible through:
# - `model.model_tag_m2m.all()`
# - and the reverse: `tag.model_tag_m2m.all()`
Tag.add_to_class(
f"{class_relation_name}s",
models.ManyToManyField(model_class, through=model_tag_class, related_name="tags"),
)