Классификация документов с переменным набором меток

#django #django-models

#django #django-модели

Вопрос:

Я хочу создать модель, в которой пользователь может определить набор меток с целью классификации документов. Каждая метка для этого документа также должна иметь вероятность (с плавающей запятой), что этот документ принадлежит этой метке.

Итак, это то, что у меня есть для моей модели с 3 метками (новости, бизнес, спорт):

 class Document(models.Model):
    document_name = models.CharField(max_length=100)
    proba_label_news = models.DecimalField(max_digits=5)
    proba_label_business = models.DecimalField(max_digits=5)
    proba_label_sports = models.DecimalField(max_digits=5)
    ...
 

Но, конечно, может быть больше меток, которые пользователь может определить в начале проекта классификации и которые разработчик не может предвидеть.
Я пробовал manytomany в качестве альтернативы, но когда я создаю модель ярлыка и определяю новую метку как «новости», у меня не может быть разной вероятности для каждой метки документа, верно?

Итак, каков способ django для решения этой проблемы?

Ответ №1:

Да, отношения «многие ко многим» могут работать. Что вам нужно добавить, так это промежуточную сквозную модель для хранения вероятности для каждого отношения документ-метка. Что-то вроде этого:

 class Label(models.Model):
    name = models.CharField(max_length=50)

class LabelProbability(models.Model):
    label = models.ForeignKey(Label, on_delete=models.CASCADE)
    document = models.ForeignKey("Document", on_delete=models.CASCADE)
    probability = models.DecimalField(max_digits=5)

class Document(models.Model):
    document_name = models.CharField(max_length=100)
    labels = models.ManyToManyField(Label, through=LabelProbability)
 

Затем, когда вы хотите добавить метку в документ, вы должны использовать through_defaults аргумент для присвоения вероятности. Сделайте что-то вроде следующего:

 news = Label.objects.get(name="news")
document_1.labels.add(news, through_defaults={"probability":0.57})
 

Вы можете прочитать больше о полях «многие ко многим» и использовании сквозной таблицы в документах django здесь

Альтернативный подход

В качестве альтернативы, вы могли бы сохранить метку и вероятность вместе, что-то вроде этого:

 class Label(models.Model):
    name = models.CharField(max_length=50)
    probability = models.DecimalField(max_digits=5)
    document = models.ForeignKey("Document", on_delete=models.CASCADE)

class Document(models.Model):
    document_name = models.CharField(max_length=100)
 

Таким образом, у вас есть только две таблицы, и в каждой метке хранится как имя метки (позволяющее использовать любое имя), так и вероятность. Вы можете добавить столько меток, сколько хотите, указывающих на один и тот же документ (как и раньше).