Как я могу добавить тот же объект в поле ManyToMany? - PullRequest
1 голос
/ 06 сентября 2010

Мне нужна помощь о том, как сохранить тот же (ссылка на) объект в ManyToManyField.Например, у меня есть такие модели:

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

class Compound(models.Model):
    materials = models.ManyToManyField(Material)

В этом примере Compound может быть изготовлен из одного или нескольких различных Material с, а также может быть сделан из того же Material дважды (то же самое id в Material модели).

Если я пытаюсь сохранить через ModelForm, второй Material сбрасывается, потому что он имеет тот же id как первый Material.

Каков наилучший подход для этого?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 06 сентября 2010

Я бы предложил сделать это согласно http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

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

class Compound(models.Model):
    materials = models.ManyToManyField(Material, through='CompoundMaterials')

class CompoundMaterials(models.Model)
    Material = models.ForeignKey(Material)
    Compound = models.ForeignKey(Compound)
    Quantity = models.IntegerField()

Что я здесь делаю? Ну, Django обычно автоматически генерирует промежуточную таблицу для хранения пар ключей, связывающих соединения с элементами. В этом случае мы определяем это сами, но не только это, мы добавляем дополнительные данные в отношение, то есть количество, о котором вы говорите.

В качестве примера использования вы можете сделать следующее:

$ python manage.py shell
from project.app.models import *

oxygen = Material(name="oxygen")
hydrogen = Material(name="hydrogen")
water = Compound(name="water")

oxygen.save()
hydrogen.save()
water.save()

water_chemistry_oxygen = CompoundMaterials(Material=oxygen, Compound=Water, Quantity=1)
water_chemistry_hydrogen = CompoundMaterials(Material=hydrogen, Compound=Water, Quantity=2)

water_chemistry_oxygen.save()
water_chemistry_hydrogen.save()
1 голос
/ 06 сентября 2010

Не используйте ManyToManyField -
Создайте новую модель (например, MaterialOfCompound), которая содержит две ForeignKey s - одну для Material записи и одну для Compound объекта.

Затем, чтобы найти все материалы, из которых состоит соединение, вы можете использовать:

[x.material for x in MaterialOfCompound.filter( compound = my_compound ) ]

или что-то подобное.

...