Django:模型通过中间模型具有两个ManyToMany关系 [英] Django: model has two ManyToMany relations through intermediate model

查看:133
本文介绍了Django:模型通过中间模型具有两个ManyToMany关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我是Django的新手,想描述一下这种情况:有一堆,还有一堆项目。 b

我有以下模型:

  class Item(models.Model):
title = models.CharField(max_length = 1024,blank = False)

def __unicode __(self):
return self.title

class Person(models.Model ):
name = models.CharField(max_length = 127,blank = False)
out_item = models.ManyToManyField(
Item,
through ='Event',
through_fields =('from_user','item'),
related_name ='giver'

in_item = models.ManyToManyField(
Item,
through ='Event ',
through_fields =('to_user','item'),
related_name ='receiver'


def __unicode __(self):
返回self.name

类Event(models.Model):
项目=模型.ForeignKey(项目)
from_user =模型.ForeignKey(人,related_name ='event_as_giver')
to_user = models.ForeignKey(Person,related_name ='event_as_receiver')

但是 makemigrations 告诉我 app.Person:(models.E003)该模型通过中间模型'app.Event'具有两个多对多关系。



我想知道我做错了什么吗?还是实现该方案的一种干净方法是什么?也许我可以将 Event 分为 GiveEvent ReceiveEvent ?但这从直觉上来说意义不大,因为传递项目时实际上只有一个事件。

解决方案

您要做什么描述听起来足够合理。出于技术原因,可能不允许这样做;一个语义上的原因是,每个 ManyToManyField 都意味着创建了一个新表,并且不能有两个具有相同名称(即由相同类表示)的表。 / p>

一种替代方法(更短和更多的DRY)将是:

  class Person(models.Model):
名称= models.CharField(max_length = 127,blank = False)
to_users = models.ManyToManyField(
'self',
对称= False,
related_name ='from_users',
through ='Event',
through_fields =('from_user','to_user'),


class Event(models.Model):
item = models.ForeignKey(Item,related_name ='events')
from_user = models.ForeignKey(Person,related_name ='events_as_giver')
to_user = models.ForeignKey(Person,related_name ='events_as_receiver')

表结构相同,但描述符是不同的。访问相关的要容易一​​些,但是访问相关的则要困难一些(例如,代替 person.out_items.all(),您会说 Item.objects.filter(events__from_user = person).distinct())。


So I am new to Django, and want to describe the scenario: there are a bunch of Persons, and there are a bunch of Items, and a person passes Items to another Person.

I have the following model:

class Item(models.Model):
    title = models.CharField(max_length=1024, blank=False)

    def __unicode__(self):
        return self.title

class Person(models.Model):
    name = models.CharField(max_length=127, blank=False)
    out_item = models.ManyToManyField(
        Item,
        through='Event',
        through_fields=('from_user', 'item'),
        related_name='giver'
    )
    in_item = models.ManyToManyField(
        Item,
        through='Event',
        through_fields=('to_user', 'item'),
        related_name='receiver'
    )

    def __unicode__(self):
        return self.name

class Event(models.Model):
    item = models.ForeignKey(Item)
    from_user = models.ForeignKey(Person, related_name='event_as_giver')
    to_user = models.ForeignKey(Person, related_name='event_as_receiver')

But makemigrations tells me app.Person: (models.E003) The model has two many-to-many relations through the intermediate model 'app.Event'.

I wonder what I did wrong? Or what is a clean way to achieve the scenario? Perhaps I can separate Event into GiveEvent and ReceiveEvent? But that just makes less sense intuitively, since there is actually only a single event when item is passed.

解决方案

What you're describing sounds reasonable enough. There may be a technical reason why that's disallowed; one semantic reason is that each ManyToManyField implies the creation of a new table, and there can't be two tables with the same name (i.e. represented by the same class).

One alternative approach (shorter and more DRY) would be this:

class Person(models.Model): 
    name = models.CharField(max_length=127, blank=False)
    to_users = models.ManyToManyField(
        'self', 
        symmetrical=False, 
        related_name='from_users',
        through='Event', 
        through_fields=('from_user', 'to_user'),
    )

class Event(models.Model):
    item = models.ForeignKey(Item, related_name='events')
    from_user = models.ForeignKey(Person, related_name='events_as_giver')
    to_user = models.ForeignKey(Person, related_name='events_as_receiver')

The table structure is the same but the descriptors are different. Accessing related people is a bit easier but accessing related items is a bit harder (for example, instead of person.out_items.all() you would say Item.objects.filter(events__from_user=person).distinct()).

这篇关于Django:模型通过中间模型具有两个ManyToMany关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆