#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)
Таким образом, у вас есть только две таблицы, и в каждой метке хранится как имя метки (позволяющее использовать любое имя), так и вероятность. Вы можете добавить столько меток, сколько хотите, указывающих на один и тот же документ (как и раньше).