test creation of object with group id attribut

Hello, I am trying to create test for my app

in the model.py I have this

class Marketplaces(models.Model):
    name = models.CharField(max_length=60, unique=True)
    group_id = models.ForeignKey(Group, on_delete=models.CASCADE)

So to create an object in my test I need to give a group

def test_marketplaces(self):
        groupTest2 = Group.objects.create(name='GroupTest2')
        userTest2 = User.objects.create_user(username="UserTest2")
        groupTest2.user_set.add(userTest2)
        marketplace = Marketplaces.objects.create(name='Market',
                                                  group_id=userTest2.groups.all().first().id)

But when I do this or I use group_id=groupTest2.pk

I get the error : ValueError: Cannot assign “3”: “Marketplaces.group_id” must be a “Group” instance.
I don’t understand the error. How am I supposed to write it correctly?

1 Like

You’re creating confusion for yourself by naming your field group_id, because that field in the object is an instance of Group, not just the id.

I suggest you rename that field.

Now, in addition to that, the message is actually very straight-forward.

That means you want to pass the object instance, not the id attribute of the group you wish to assign.

1 Like

Thanks for your answer, but I don’t understand it completely:
When I check the database, for each market I have in the column group_id_id a value like 1, or 2

It is for this reason that I try to get the pk of the group.
But I am wrong about it ?
And how do I get the group instance of the groupTest2 for example ?

1 Like

You have:

This is returning the id field of the userTest2 object selected by the query.

This means that this:
userTest2.groups.all().first()
is a reference to the object itself.

I suggest you take some time to read and understand the docs for ForeignKey fields to understand what this all means.

I am sorry but I don’t understand you answer.
For me when I create the groupTest2 I got the id 1
When I create the userTest2 and add it to the groupTest2 I should have 1 again.
When I create the object marketplace when I give the group I still should have 1
If I use userTest2.groups.all().first().id for the group I got the error

ValueError: Cannot assign "1": "Marketplaces.group_id" must be a "Group" instance.

And if I use group_id=userTest2.groups.all().first() I got no error during the run but I got the error during the comparison

        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)
        expected = [
            {
                'id': marketplace.id,
                'name': marketplace.name,
                'group_id': marketplace.group_id,
            }
        ]
        self.assertEqual(expected, response.json())

I got this

First differing element 0:
{'id': 1, 'name': 'Supermarché', 'group_id': <Group: GroupTest2>}
{'id': 1, 'name': 'Supermarché', 'group_id': 1}

So if I have ‘group_id’: <Group: GroupTest2> on the first line how could it get ‘group_id’: 1 on the second one?

Have you fixed the name of your field in Marketplace yet?
(Changed group_id = ... to group = ?)

That’s going to affect my answer.

In the example no.
But I found a solution. And I start to understand
In fact I was miss understanding the output

First differing element 0:
{'id': 1, 'name': 'Supermarché', 'group_id': <Group: GroupTest2>} 
{'id': 1, 'name': 'Supermarché', 'group_id': 1}

The first dictionary {'id': 1, 'name': 'Supermarché', 'group_id': <Group: GroupTest2>} is the result of the expected, and this from the table {'id': 1, 'name': 'Supermarché', 'group_id': 1}
So if I wrote

        expected = [
            {
                'id': marketplace.id,
                'name': marketplace.name,
                'group': marketplace.group_id.id,
            }
        ]

Is my conclusion right ?

As you advise I change the code
So the new code and it works

class Marketplaces(models.Model):
    name = models.CharField(max_length=60, unique=True)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)

and the new test :

def test_marketplaces(self):
        groupTest2 = Group.objects.create(name='GroupTest2')
        print('groupTest2', groupTest2.id)
        userTest2 = User.objects.create_user(username="UserTest2")
        groupTest2.user_set.add(userTest2)
        print('UserTest 2 group.id ', userTest2.groups.all().first().id)
        marketplace = Marketplaces.objects.create(name='Market', group=userTest2.groups.all().first())     
          
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)
        expected = [
            {
                'id': marketplace.id,
                'name': marketplace.name,
                'group': marketplace.group.id,
            }
        ]
        self.assertEqual(expected, response.json())

Always for my understanding when I create group = models.ForeignKey(Group, on_delete=models.CASCADE).
On the database side I got the pk of the Group in field “group”, but on the python side I got directly the group. And I never got the id of the group from the table Marketplace but from the table Group through the link automatically created.