如何在Django表单中包含id字段?

4
我正在尝试创建一个简单的表单,通过在表单中输入记录的ID来检索该记录。
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

从django导入表单 从django.forms导入ModelForm 从transactions.models导入账单(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})

然而,在模板上当我使用{{ form.as_p }}时,我什么都看不到。你有什么想法吗?
2个回答

7

这是一个不应该使用ModelForm的情况。Fazil已经给出了关于主键是什么以及为什么不应该尝试更新它的好答案。但这就是模型表单的作用。

另一方面,有些情况下客户被要求提供“参考号”,这种参考号通常是主键。因此,在这种情况下,解决方案是使用简单的表单而不是模型表单。

class BillSelectForm(forms.Form):
    pk = forms.IntegerField()

然后

if request.method == 'POST':
    form = BillSelectForm(request.POST)
    if form.is_valid():
        bill = Bill.objects.get(form.cleaned_data['pk'])

else:
    form = BillSelectForm()

谢谢,这就是我在寻找的!只是提醒一下,我认为这个类应该继承自 forms.Form,因为 ModelForm 会给出一个 ValueError,因为我们没有指定模型。 - halsdunes
抱歉,打错了。感谢指出。祝您的项目顺利。 - e4c5
谢谢你,e4c5! :) - halsdunes
这让我很烦恼,因为某种原因我使用了“id”而不是“pk”。谢谢! - fang_dejavu

1

ID是Django模型中自动添加的主键字段,仅当模型中未设置主键时才会出现。该字段不能用于修改现有对象或创建新对象。即使我们试图修改它,也会在旧对象旁边创建一个新对象。使用它作为特定对象的参考要比作为字段参数更好。

从文档中可以了解到:

primary_key

如果为True,则此字段是模型的主键。

如果您没有为模型中的任何字段指定primary_key=True,则Django将自动添加一个IntegerField来保存主键,因此除非要覆盖默认的主键行为,否则不需要在任何字段上设置primary_key=True。有关详细信息,请参见自动主键字段。

主键字段是只读的。如果您更改现有对象的主键值,然后保存它,将在旧对象旁边创建一个新对象。

你可以像这样在模板中使用ID字段:{{ object.auto_id }}

为什么要在表单中使用ID字段?


谢谢回复!我想做的是让用户输入账单记录的ID来定位它,而不是使用其他属性--它基本上是一个只使用ID值进行搜索的搜索框。 - halsdunes
哈哈,这正是我在看到这条评论前输入答案时想到的 :) - e4c5
@zaidfazil 我正在学习Django(所以请原谅任何无意的愚蠢),但是假设您想在屏幕上显示记录以便用户可以编辑它(当然除了id字段)。难道您不需要在表单中存储id,然后将其显示在屏幕上,即使您将其隐藏,使用户看不到吗?如果不是这样,那么如何获取id以知道要编辑哪个记录?如果他们没有在HTML表单中存储记录ID,人们会如何处理这种情况?我显然在这里缺少了什么,因此非常感谢任何帮助。谢谢! - Ben
如果您正在使用ModelForm,则可以将要编辑的对象传递到表单中,它会处理其余部分。如果没有,则为了显示现有数据,您拥有id,它是主键,可以在所需编辑后用于进行PUT/PATCH请求。在Django模板中,您不必显式存储id,上下文字典肯定包含对象的id。 - zaidfazil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接