1

I have django Student model like below

class Student(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=20)
    score = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return f"Student(id: {self.id}, name: {self.name}, salary: {self.score})"

I have created some users in database also below is django shell output

>>> s = Student.objects.create(name="erik", score=90)
>>> print(s)
Student(id: None, name: erik, salary: 90)   # <----- here is showing id None
>>> Student.objects.all()                                                                                                       
<QuerySet [<Student: Student(id: 1, name: alex, salary: 40.00)>, <Student: Student(id: 2, name: john, salary: 60.00)>, <Student: Student(id: 3, name: erik, salary: 90.00)>]>

when i have called Student.objects.all() then it is showing id.

I want to get id from s variable because i am performing unit testing like below.

class GetSingleStudentTest(TestCase):

    def setUp(self):
        Student.objects.create(name="student1", score=50)
        Student.objects.create(name="student2", score=55)
        Student.objects.create(name="student3", score=80)
        Student.objects.create(name="student4", score=36)

    def test_get_single_student(self):
        # get API response
        response = client.get(reverse("student-detail", kwargs={"pk" : self.student2.pk }))

        # get data from db
        student = Student.objects.get(pk=self.student2.pk)
        serializer = StudentSerializer(student)
        self.assertEqual(response.data, serializer.data)

So when i have tried to access self.student2.pk it is None like we saw in django shell also. So how can i get that id?

because as i know Model.objects.create creates a user and also save into database then why id is None here? I am learning from this guide https://realpython.com/test-driven-development-of-a-django-restful-api/ but they not showed this kind of issues that's why I asked here. I have used setUpTestData method also but same kind of issue is there.

I think AutoField is working perfectly. Is it same as IntegerField but i have specified primary_key=True.

Thank you.

Visrut
  • 360
  • 4
  • 14
  • Did you add that `id` field later? I assume you didn't have that field declared on your model at the start and later added it (and didn't run `makemigrations` and `migrate` either) Otherwise I don't know how you are _not getting an error_. – Abdul Aziz Barkat Sep 18 '21 at 16:33
  • 1
    You are not assigning anything to the id, its just a primary key. If you are expecting autoincrement, use `AutoField ` instead of IntegerField. Also im confuse how it is showing for queryset then. – Summer Sep 18 '21 at 17:10
  • @AbdulAzizBarkat No i did't add it later and i also have done migrations at first. – Visrut Sep 19 '21 at 02:48
  • @Summer you are absolutely right thanks. – Visrut Sep 19 '21 at 03:09
  • 1
    I suggest you remove the manual field `id = ...` in your model. Django then generates automatically a field called `id` which is the primary key with auto increment set to True. – physicalattraction Sep 19 '21 at 08:39

1 Answers1

0

You need to save() the object so that pk is assigned. Also, you may refer to official doc at: https://docs.djangoproject.com/en/3.2/ref/models/instances/#auto-incrementing-primary-keys

Ahmed Ablak
  • 718
  • 3
  • 14
  • 1
    I think `create` method is used to `create and save` object in single step. I have read it here https://stackoverflow.com/questions/26672077/django-model-vs-model-objects-create – Visrut Sep 18 '21 at 16:28
  • hi @Visrut you are probably right. – Ahmed Ablak Sep 18 '21 at 16:49