Python Django中如何让model field在form上自动显示?
我是初学者,请老师们见谅,接触这一块也是工作需要.
多谢各位!
我设计了三个 model :
class Unit(models.Model):
FName = …
…
class Goods(models.Model):
FUnitID = models.ForeignKey(Unit,…)
…
class SaleOrderEntry(models.Model):
FGoodsID = models.ForeignKey(Goods,…)
FUnitID = ???
…
我的想法:
在 SaleOrderEntry 这个表中,我需要一个 FUnitID 字段来存储 Goods (货物) 的计量单位(以 Unit 表主键形式存储),
我希望实现:
在 admin site 的 form 中,增加一个 SaleOrderEntry 实例时,"计量单位"是随着 Goods 字段的选择而自动出现,随之而改变的.
而且自动显示的 Unit 是 name ,而不是 Autofield : id .
我能想到的(我太菜了):
我觉得 FUnitID 也应该定义成: FUnitID = models.ForeignKey(Unit,…)
但怎么才能在 form 上实现"随着 Goods 字段的选择而自动出现"呢?
请老师们帮忙.谢谢了.
Python Django中如何让model field在form上自动显示?
obj = SaleOrderEntry.objects.get(pk=pk)
“计量单位” = obj. FGoodsID. FUnitID.FName
在Django里,让model的字段自动在form里显示,最直接的方法就是用ModelForm。这玩意儿就是干这个的,它能根据你的model定义自动生成对应的form字段。
核心就两步:
- 在你的
forms.py里创建一个继承自forms.ModelForm的类。 - 在这个类里,通过
Meta类指定对应的model和你想包含的字段。
下面是个完整的例子:
假设你有个简单的Book model在models.py里:
# models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
published_date = models.DateField()
isbn = models.CharField(max_length=13, unique=True)
要让这个model的字段自动变成form,就在forms.py里这么写:
# forms.py
from django import forms
from .models import Book
class BookForm(forms.ModelForm):
class Meta:
model = Book # 指定对应的model
fields = '__all__' # 包含所有字段
# 或者指定特定字段:fields = ['title', 'author', 'published_date']
然后在你的view里直接用这个BookForm就行:
# views.py
from django.shortcuts import render
from .forms import BookForm
def create_book(request):
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
form.save() # 直接保存到数据库
# 重定向或其他成功处理
else:
form = BookForm()
return render(request, 'book_form.html', {'form': form})
在模板book_form.html里,直接渲染form:
<form method="post">
{% csrf_token %}
{{ form.as_p }} <!-- 这会自动渲染所有字段 -->
<button type="submit">提交</button>
</form>
ModelForm会自动:
- 根据model字段类型选择对应的form字段(比如
CharField变成TextInput,DateField变成DateInput) - 应用model里定义的验证规则(比如
max_length、unique等) - 显示model里定义的
verbose_name作为标签
如果你需要自定义某个字段的显示(比如改widget、加help_text),可以在BookForm类里直接覆盖那个字段的定义:
class BookForm(forms.ModelForm):
published_date = forms.DateField(
widget=forms.SelectDateWidget(years=range(2000, 2030)),
help_text="选择出版日期"
)
class Meta:
model = Book
fields = '__all__'
总结:用ModelForm就对了,省时省力。
可以在 admin site 上增加一个自定义的字段,通过一楼那样的方式访问
我经历的两家公司都不用 form…
如果是我,我这样处理:
class Goods(models.Model):
…def str(self):
…return self.name+self.FUnitID.FName
(个人以为 admin 不用过于追去个性化,性价比太低;如果必须个性化,就自己写一个页面)
静态显示,但没按 save 按钮,不会动态变化
class SaleOrderEntry(models.Model):
…def get_FName(self):
…return self.FGoodsID.FUnitID.FName
…get_FName.short_description = ‘计量单位’
4L 的设置,目的是新增 SaleOrderEntry 时有计量单位的提醒
5L 的设置,目的是修改或查看时,显示计量单位提醒
首先你要先解释什么叫“随着 Goods 字段的选择而自动出现”。
老师,我的水平还处于没有分辨能力的阶段,:)
不用 form?用 table?
老师好,我水平低啊,表达不清晰.
选择 货物 自动带出 计量单位 ,数据表里村的是 Unit 的 id , 页面上显示的是 Unit 的 FName .
谢谢老师.
因为我刚开始学习 Django, 目的是想快速实现一个初级版本.
我是想学习了解 admin 的实现方式,然后再自己做页面.
刚开始,知识面捉襟见肘.
我自己有几年传统 ERP 的实施和开发经历,也仅仅对这些技术有了解,仅仅对数据库的 CRUD ,触发器,约束,等等需要用到的知识有了解.
本科是学财务的,看懂 python 和 django 的英文文档没问题,但也仅仅在看懂和理解,融会贯通还很远.
也在网罗一些伙伴,但无奈,专业的瞧不起我现在的项目需求;不专业的又帮不上我.
您给我的回复我马马虎虎看得懂,谢谢.
您觉得像 SaleOrderEntry 这种单据表,还需要存 UnitID 这种字段吗? 每个 goods 对应的 unit 已经在 goods 表里有了.
这个的话,应该是要用 js 去做一个联动查询
https://www.google.com/search?q=django%20admin%20js%20%E8%81%94%E5%8A%A8&safe=off&cad=h
随便打开一个链接,看下怎么处理 js 这一块
到时 change 的时候,fiilter(goods=goods).first()就算了,试下
谢谢老师!!!
如果你技术扎实,就按照 的搜索页面找找方案,我看了一下,的确能实现你说的效果
如果那些文章有点吃力,就不要勉强了,先把整体做好,最后再雕琢这种提升体验的细节
至于单位要不要单独弄个表,这个涉及到架构了,我也没什么好的建议,如果是我,可能会选 choices
https://docs.djangoproject.com/en/2.1/ref/models/fields/
非常感谢!!!
我接受而且非常赞同您的建议,“先把整体做好,最后再雕琢这种提升体验的细节”.
先把能做的做了再说,也许知识点在哪天就被覆盖了.
thx v m

