How do I include the id field in a django form?

15,154

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??

Share:
15,154
halsdunes
Author by

halsdunes

Updated on June 26, 2022

Comments

  • halsdunes
    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
    halsdunes almost 7 years
    Thanks 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
    e4c5 almost 7 years
    Ha this is what I thought, when I typed my answer before seeing this comment :)
  • halsdunes
    halsdunes almost 7 years
    Thanks, this is what I was looking for! Just a heads up, I think the class should inherit from forms.Form, since ModelForm gives a ValueError since we're not specifying a Model.
  • e4c5
    e4c5 almost 7 years
    Sorry, Typo. Thanks for pointing out. All the best with your project
  • halsdunes
    halsdunes almost 7 years
    Thank you e4c5! :)
  • Ben
    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
    zaidfazil over 6 years
    If 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 the id, 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
    fang_dejavu almost 5 years
    This was killing me, for some reason I was using 'id' instead of 'pk'. Thanks!