How can I add the same object to a ManyToMany field?

痴心易碎 提交于 2019-12-11 12:16:01

问题


I need help on how to save the same (reference to an) object into a ManyToManyField. For example I have models like this:

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

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

In this example, the Compound can be made of one or many different Materials, and it also could be made from the same Material twice (same id in Material model).

If I try to save through a ModelForm, the second Material is discarded because it has the same id as the first Material.

What is the best approach for this?

Thank you!


回答1:


I would suggest doing this as per 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()

What am I doing here? Well, Django normally automatically generates an intermediary table for holding pairs of keys associating compounds to elements. In this case we're definiting it ourselves, but not only that, we're adding additional data to the relationship i.e. the quantity you speak of.

As an example usage, what you might do is this:

$ 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()



回答2:


Don't use a ManyToManyField -
Create a new model (MaterialOfCompound, for example), which holds two ForeignKeys - one to a Material record and one to a Compound object.

Then, to find all materials a compound is made of, you could use:

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

or something similar.



来源:https://stackoverflow.com/questions/3652888/how-can-i-add-the-same-object-to-a-manytomany-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!