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上自动显示?


17 回复

obj = SaleOrderEntry.objects.get(pk=pk)

“计量单位” = obj. FGoodsID. FUnitID.FName


在Django里,让model的字段自动在form里显示,最直接的方法就是用ModelForm。这玩意儿就是干这个的,它能根据你的model定义自动生成对应的form字段。

核心就两步:

  1. 在你的forms.py里创建一个继承自forms.ModelForm的类。
  2. 在这个类里,通过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变成TextInputDateField变成DateInput
  • 应用model里定义的验证规则(比如max_lengthunique等)
  • 显示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 这一块

到时 change 的时候,fiilter(goods=goods).first()就算了,试下

谢谢老师!!!

如果你技术扎实,就按照 的搜索页面找找方案,我看了一下,的确能实现你说的效果
如果那些文章有点吃力,就不要勉强了,先把整体做好,最后再雕琢这种提升体验的细节
至于单位要不要单独弄个表,这个涉及到架构了,我也没什么好的建议,如果是我,可能会选 choices
https://docs.djangoproject.com/en/2.1/ref/models/fields/

非常感谢!!!
我接受而且非常赞同您的建议,“先把整体做好,最后再雕琢这种提升体验的细节”.
先把能做的做了再说,也许知识点在哪天就被覆盖了.
thx v m

回到顶部