Tuesday, July 23, 2019

Re: M2M relationship not behaving as I would expect

FYI, I was able to get this working with a small change to the query, from:

data = list(TestThing.objects.all().values('user__user_data',
                                           'thing_data',
                                           'user__testbridge__bridge_data'))

to:

data = list(TestThing.objects.all().values('user__user_data',
                                           'thing_data',
                                           'testbridge__bridge_data'))

(removing the highlighted code).

Somehow this extra level of indirection caused the query to lose the constraints of the one-to-many relationships between user and bridge and between thing and bridge, although I don't fully understand it.

Thanks for your response Mike.

-Don


On Sunday, July 21, 2019 at 3:58:03 PM UTC-7, Mike Dewhirst wrote:
You can constrain uniqueness in the through table and/or the other tables to represent whatever real-world constraints you need. Otherwise you can have as many duplicated relationships as you want. Each through record has its own id so the database is happy no matter how many go in.

Connected by Motorola


Don Baldwin <donaldo...@gmail.com> wrote:

Hi,

I have a many-to-many relationship between users and things, where a user can select multiple things,
and a thing can be selected by multiple users. The relationship between users and things also
contains data, so I've specifically setup a through table.

When I add a user to a thing, I guess I expect a one-to-one relationship between the thing and
the intervening bridge, but it seems like I'm getting a one-to-many.

Here is my code:

models.py:

class TestUser(models.Model):
user_data = models.TextField(default="")

def __str__(self):
return "Other: " + self.user_data

class TestThing(models.Model):
thing_data = models.TextField(default="")
user = models.ManyToManyField(TestUser, through='TestBridge')

def __str__(self):
return "Thing: " + self.thing_data

class TestBridge(models.Model):
user = models.ForeignKey(TestUser, on_delete=models.CASCADE)
thing = models.ForeignKey(TestThing, on_delete=models.CASCADE)
bridge_data = models.TextField(default="")

def __str__(self):
return "Bridge: " + self.bridge_data

tests.py:

u_1 = TestUser(user_data = 'user')
u_1.save()
t_1 = TestThing(thing_data='thing 1')
t_1.save()
t_2 = TestThing(thing_data='thing 2')
t_2.save()

t_1.user.add(u_1, through_defaults={'bridge_data': 'bridge 1'})
t_2.user.add(u_1, through_defaults={'bridge_data': 'bridge 2'})

data = list(TestThing.objects.all().values('user__user_data',
'thing_data',
'user__testbridge__bridge_data'))
for item in data:
print(item)

Output:

{'user__user_data': 'user', 'thing_data': 'thing 1', 'user__testbridge__bridge_data': 'bridge 1'}
{'user__user_data': 'user', 'thing_data': 'thing 1', 'user__testbridge__bridge_data': 'bridge 2'}
{'user__user_data': 'user', 'thing_data': 'thing 2', 'user__testbridge__bridge_data': 'bridge 1'}
{'user__user_data': 'user', 'thing_data': 'thing 2', 'user__testbridge__bridge_data': 'bridge 2'}

What I expect:

{'user__user_data': 'user', 'thing_data': 'thing 1', 'user__testbridge__bridge_data': 'bridge 1'}
{'user__user_data': 'user', 'thing_data': 'thing 2', 'user__testbridge__bridge_data': 'bridge 2'}

How do I get rid of the relationships between thing 1 and bridge 2, and between thing 2 and bridge 1?
Thanks for your responses.
-Don

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAKL%3DYPH5OCd9wYNG%2BZ4R0%3DuYOEW0hfhRngqfudeaGqCjB6Yfrg%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/2d668b13-cbfe-4fe3-bf92-9bd2900ec26b%40googlegroups.com.

No comments:

Post a Comment