3

I am attempting to save a simple device model, which has three fields, username, device_name and manufacturer.

Looking at the model in the Database, an ID field was added as the Primary Key. This field should auto increment.

After reading some documentation, I have tried to recreate the following even:

Auto-incrementing primary keys¶

If a model has an AutoField — an auto-incrementing primary key — then that 
auto-incremented value will be calculated and saved as an attribute on your 
object the first time you call save():

>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
>>> b2.id     # Returns None, because b doesn't have an ID yet.
>>> b2.save()
>>> b2.id     # Returns the ID of your new object.

When doing that for my device model:

>>> d = Device("username123", "device12", "manufact12")
>>> d.id
>>> 'username123'

If I attempt to save this model it will give me the following error:

ValueError: invalid literal for int() with base 10: 'username123'

So it is trying to save 'username123' as the ID. If I create the following device:

>>> d = Device("1", "username123", "device12", "manufact12")

It creates the device with no problem.

Can anyone explain why this is happening?

Edit: After seeing the first reply, it seems that my post was not clear. Here is my model from Django:

class Device(models.Model):
    username = models.CharField(max_length=100)
    device_name = models.CharField(max_length=100)
    manufacturer = models.CharField(max_length=100)

It does not have an ID. As I said in my post, when I try to create the model without the ID (as I would expect to do) it gives me an error. If I explicitly state an ID it works, but as you said, that is not how this is supposed to work.

Archetype
  • 197
  • 3
  • 14
  • https://stackoverflow.com/questions/65760979/django-rest-framework-with-mongodb-not-creating-auto-field-primary-key-id – san Jan 18 '21 at 19:09

1 Answers1

8

You need to understand what does auto incrementing mean. It means it's an integer that increases by itself so you don't need to bother assigning a new integer to it every time you create a database record. If you insert the first record, database would automatically give it id as 1. Next time you inserts a records, database gives it id 2 and so on.

You were trying to give username123 to the id field, which there's no way for django(and for anybody) to know what's the next available id for username123.

So the best action is: never explicitly give an id to a model object, because your database will generate one for you. I hope that makes sense.

Edit:

You should NEVER create an object this way:

d = Device("username123", "device12", "manufact12")

It's a common bad practice for sql statement and django as well: not specify which field to take which value. If your model changed later, you would assign the value to the wrong field. Always do this:

d = Device(field1="username123",
           field2="device12",
           field3="manufact12")

Also for completeness, the error you had was telling you: since you didn't specify which value assign to which field, I would assign them in sequence, so the first value should assign to id. However, since id field is an integer field(auto increment), I would try to use int() to convert it to integer and store the value. But apparently int("username123") is invalid statement, hence the error.

Shang Wang
  • 24,909
  • 20
  • 73
  • 94
  • Yup, your Edit fixed the problem. Interesting. I still don't really understand why it was either A) Wanting me to specify the ID, or B) Giving me an error if I didn't specify the ID. None of the Django documentation talks about specifying the ID, as if it is created when you save your model. Heck, even the example I gave above from Django docs shows what I just described. – Archetype May 18 '16 at 13:34
  • Excellent, thank you for the complete answer. Very well done! I don't have the REP to upvote you, but you earned it! – Archetype May 18 '16 at 13:40