I was making an E Commerce website and added various products in it. Now for making a cart i made a add to cart button. And in HTML i assigned an id to this button. The id was pr{{product.id}}. I have not made buttons individually for every item. There is a for loop running which creates buttons. Now My doubt is that i have not assigned any field id in the models class. But still this code is running and when i printed the id's on the console i realised that it prints like pr32, pr33, pr34 ie in a sequential manner. So is there any product.id field predefined in django??
My doubt is that I have not assigned any field id in the models class.
You don't need to. If you do not add a primary key yourself, Django will add a field with the name id that is an AutoField. This is documented in the Automatic primary key fields section of the documentation:
By default, Django gives each model the following field:
id = models.AutoField(primary_key=True)
This is an auto-incrementing primary key.
If you’d like to specify a custom primary key, specify
primary_key=True on one of your fields. If Django sees you’ve
explicitly set Field.primary_key, it won’t add the automatic id
column.
Each model requires exactly one field to have primary_key=True
(either explicitly declared or automatically added).
So to answer your question:
So is there any product.id field predefined in django?
Yes, if you did not specify a field with primary_key=True yourself.
Related
Is it possible to get the id of the user who created a specific item, no matter what it, in Django? I have a site where when the users are authenticated can access a form and submit a new item. Can I retrieve who created what without adding an extra 'submitted by'
Event.objects.filter(owner=self.kwargs['pk'])
(which gives me name 'self' is not defined )?
You cannot access the information without adding a new field, but you can have a look at this library django-audit-log for easy tracking. It will add created_by and modified_by fields and maintain them.
I use Django 2
This is what my view.py contains
class SchoolCreateView(CreateView):
fields = ("name","principal","location")
model = models.School
The template (html file) used by this view contains the code:
form.instance.pk
And it works. It returns the correct primary key. I don't understand why.
Why does this work when I have not defined the form object in my view? Is the value of form automatically assigned when using CBVs in Django?
Follow up question. I know that form.instance represents a row in the model but what does form itself represent? My current understanding with forms is that it represents request.POST from views.py (basing my knowledge from function views). But that wouldn't make sense because the client has yet to make a POST request since he is still going to create a data entry which will be posted but is not being posted yet.
Pk is a primary key field, which is id by default. if you define other field as primary key, calling pk will return this.
From documentation:
By default, Django gives each model the following field:
id = models.AutoField(primary_key=True)
This is an auto-incrementing primary key.
If you’d like to specify a custom primary key, specify primary_key=True on one of your fields. If Django sees you’ve explicitly set Field.primary_key, it won’t add the automatic id column.
Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).
By default, Django gives each model the following field:
id = models.AutoField(primary_key=True)
(https://docs.djangoproject.com/en/1.10/topics/db/models/#automatic-primary-key-fields)
This is great and convenient. However, I would like to know whether it is possible to change the name of the id field to more informative name, e.g., item_id.
If this is indeed possible, how can I do that?
EDIT: From the answers I understand that it is impossible to do it without setting the primary key explicitly (which is what I wanted to know).
My model has many classes, and I think that it will be clearer to give more informative field names. Does it really matter?
You just reference the source!
If you’d like to specify a custom primary key, just specify
primary_key=True on one of your fields. If Django sees you’ve
explicitly set Field.primary_key, it won’t add the automatic id
column.
class MyModel(models.Model):
item_id = models.AutoField(primary_key=True)
Say I have a model User, which has a credits field (IntegerField). When a user registers, I will set the credits field to 0, and I will update the credits for certain events.
I don't want the user know there is a field like this in the db table.
What attribute should I set to the field?
To accomplish the defaulting to 0 part, you can simply use the default argument of the model field.
For the part where you don't want your users to know about the field, you have a couple choices.
Solution 1: Field.editable
Defining your field as follows will cause the field to never show up in a model form.
credits = models.IntegerField(default=0, editable=False)
Downsides
You won't be able to edit the field's value in the admin
Form validation will never take this field into account (e.g., def clean_credits(self): won't run)
Solution 2: ModelForm.exclude|fields
Creating a ModelForm for the model is something you're going to be doing. You can define an exclude attribute on the form's Meta class, and add "credits" to the list. See the docs linked above. You can instead define fields on the Meta class, and omit "credits". The latter of the two options is considered a better practice, particularly when pertaining to security, and is known as a whitelist.
Downsides
You have to remember to define exclude or fields on every exposed form
Updating the "secret" field
The proper way to handle specifying a "secret" field's value when the field isn't in the form is:
# Inside your view's post method (or FormView.form_valid, if you're using generic views)
instance = form.save(commit=False) # Does everything except INSERT into the database
instance.credits = <however many credits you feel like giving the user>
instance.save()
If you didn't do that, and instead just saved the form as-is, the value specified by default would be set to the instance's credits field.
You'll want to use an IntegerField with default=0: credits = models.IntegerField(default=0). Just take care not to show this field to the user in any forms or when displaying the user.
E.g., if you had a ModelForm for User, do not include credits in the fields field of Meta
It appears Django hides fields that are flagged Primary Key from being displayed/edited in the Django admin interface.
Let's say I'd like to input data in which I may or may not want to specify a primary key. How would I go about displaying primary keys in the admin interface, and how could I make specifying it optional?
I also wanted to simply show the 'id' (primary key) within the Django admin, but not necessarily edit it. I just added it to the readonly_fields list, and it showed up fine. IE:
class StudentEnrollmentInline(admin.TabularInline):
model = Enrollment
readonly_fields=('id',)
whereas if I tried to add it to the 'fields' list, Django got upset with me, saying that field didn't exist...
If you explicitly specify the primary key field in your models (with primary_key=True), you should be able to edit it in the admin.
For Django models created via ./manage.py syncdb the following primary key field is added automatically:
id = models.AutoField(primary_key=True)
if you change (or add) that to your model explicitly as an IntegerField primary key, you'll be able to edit it directly using the admin:
id = models.IntegerField(primary_key=True)
But as others pointed out, this is a potential minefield...
To show the primary key, which by default will have a column name of "id" in the database - use "pk"
def __str__(self):
return '{} - {} ({})'.format(self.pk, self.name, self.pcode)
It doesn't make sense to have an optional primary key. Either the PK is an autoincrement, in which case there's no need to edit it, or it's manually specified, in which case it is always required.
Why do you need this?
In django documentation, there is a short sentence about that, which is not clear:
If neither fields nor fieldsets options are present, Django will default to displaying each field that isn't an AutoField and has editable=True, in a single fieldset, in the same order as the fields are defined in the model.
Reason is, django do not allow you to edit an AutoField by any means (and that is the right thing since it is an auto increment value and should not be edited). #mnelson4's answer is a good approach to display it.
The answer with the highest votes didn't work for me. I needed a getter.
class StudentEnrollmentInline(admin.TabularInline):
model = Enrollment
readonly_fields=('student_enrollment_id',)
def student_enrollment_id(self, obj):
return obj.id
Using django 1.11