How do I include the id field in a django form?
Solution 1
This is a situation where you shouldn't be using ModelForm
. Fazil has given a good answer about what the primary key is and why you shouldn't try to update it. But that's what a model form is about.
On the other hand there are situations where clients are asked to provide a 'refrence number' such a reference number often happens to be a primary key. So in this case, the solution would be to use a simple Form instead of a ModelForm.
class BillSelectForm(forms.Form):
pk = forms.IntegerField()
And then
if request.method == 'POST':
form = BillSelectForm(request.POST)
if form.is_valid():
bill = Bill.objects.get(form.cleaned_data['pk'])
else:
form = BillSelectForm()
Solution 2
ID is an automatically added primary key field for models in django, only if primary key is not set in a model. The field can't be modified for an existing object or even created for a new one. Even if we tried to modify it, a new object will be created alongside the old one. It is much preferred to be used as a reference for a particular object rather than as a field parameter.
From the docs:
primary_key
If True, this field is the primary key for the model.
If you don’t specify primary_key=True for any fields in your model, Django will automatically add an IntegerField to hold the primary key, so you don’t need to set primary_key=True on any of your fields unless you want to override the default primary-key behavior. For more, see Automatic primary key fields.
The primary key field is read-only. If you change the value of the primary key on an existing object and then save it, a new object will be created alongside the old one.
You could use the ID field in template like this,. {{ object.auto_id }}
Why would you want to use ID field in a form??
halsdunes
Updated on June 26, 2022Comments
-
halsdunes almost 2 years
I'm trying to create a simple form that pulls up a record by asking its ID in the form.
views.py
class Bill(models.Model): """ Represents a single purchase made by a customer at a business. """ business = models.ForeignKey(Businesses) customer = models.ForeignKey(User, blank=True, null=True) charge = models.ForeignKey(Charge, blank=True, null=True) amount = models.IntegerField(verbose_name='Purchase amount (in cents)', validators=[MinValueValidator(0)]) tip = models.IntegerField(verbose_name='Tip amount (in cents)', validators=[MinValueValidator(0)]) comments = models.CharField(max_length=255, blank=True, null=True) timestamp = models.DateTimeField(auto_now_add=True)
forms.py
from django import forms from django.forms import ModelForm from transactions.models import Bill
class BillSelectForm(ModelForm): class Meta: model = Bill fields = ('id',)
views.py
@login_required(login_url='/sign-in/') def select_bill(request): """ Finds a bill based on its ID number. """ if request.method == 'POST': form = BillSelectForm(request.POST) if form.is_valid(): pass # look up db for id number # go to bill view page if id found AND bill not paid # go back to same page and create message saying wrong bill else: form = BillSelectForm() return render(request, 'bill_select.html', {'form': form})
However, on the template, when I use
{{ form.as_p }}
, I'm seeing nothing at all. Thoughts? -
halsdunes almost 7 yearsThanks for the reply! What I'm trying to do is essentially let the user enter the id of a Bill record to locate it, rather than use other attributes-- it would basically be a search box that only uses the id value to search.
-
e4c5 almost 7 yearsHa this is what I thought, when I typed my answer before seeing this comment :)
-
halsdunes almost 7 yearsThanks, this is what I was looking for! Just a heads up, I think the class should inherit from
forms.Form
, sinceModelForm
gives aValueError
since we're not specifying a Model. -
e4c5 almost 7 yearsSorry, Typo. Thanks for pointing out. All the best with your project
-
halsdunes almost 7 yearsThank you e4c5! :)
-
Ben over 6 years@zaidfazil Just learning Django here (so please excuse any inadvertent stupidity) but suppose you want to display a record so the user can edit it on screen (all fields but the id, of course). Don't you need to store the id somewhere in the form and then have it on the screen, even if you hide it so the user doesn't see it? If not, how to you pick up the id to know which record in your DB to edit? How do people do this if they're not storing the record id somewhere in the HTML form? I'm clearly missing something here so any help would be much appreciated. Thanks!
-
zaidfazil over 6 yearsIf you are using a
ModelForm
then the object you are trying to edit can be passed into the form and it takes care of the rest. If not, then for displaying the existing data, you do possess theid
, which is the primary_key, which can be used to do the PUT/PATCH request after the required editing. In django templating, you don't have to explicitly store the id, the context dictionary definitely contains the id of the object. -
fang_dejavu almost 5 yearsThis was killing me, for some reason I was using 'id' instead of 'pk'. Thanks!