【问题标题】:What's the best way to build up a form from 2 models with Django 1.6使用 Django 1.6 从 2 个模型构建表单的最佳方法是什么
【发布时间】:2014-01-26 14:16:15
【问题描述】:

对于一个小应用程序,我定义了两个模型:

class Pressure (models.Model):
    user = models.ForeignKey(User)
    sys = models.FloatField(blank=False, null=False, verbose_name=_(u"systolic"))
    dia = models.FloatField(blank=False, null=False, verbose_name=_(u"diastolic"))
    pulse = models.IntegerField(blank=False, null=False, verbose_name=_(u"Pulse"))
    timestamp = models.DateTimeField(verbose_name=_(u"Messurement timestamp"))

    def __unicode__(self):
        return self.timestamp.strftime("%y-%m-%d: %H-%M")

class Weight(models.Model):
    user = models.ForeignKey(User)
    weight = models.FloatField(blank=False, null=False, verbose_name=_(u"Weight"))
    timestamp = models.DateTimeField(verbose_name=_(u"Messurement timestamp"))

    def __unicode__(self):
        return self.timestamp.strftime("%y-%m-%d: %H-%M")

不,我想为这两个模型构建一个合并表单,其中用户和时间戳对于两个模型都是相同的。其余文件应该是可选的。这意味着,如果没有给出例如重量,不得插入数据库等。

我正在阅读有关 mixins 和一些表单集的信息,但不知道这里最好的方法是什么。

【问题讨论】:

    标签: python django forms mixins


    【解决方案1】:

    您不需要一个表单来处理这个问题。您只需要一个处理两个模型的表单的视图。基本思想很简单:创建两个表单类,并在同一个<form> 元素中呈现给用户。提交时,检查两个表单是否有效,然后将它们都保存并将用户发送到下一页。它看起来像这样:

    from django import forms
    from django.contrib.auth.decorators import login_required
    from django.shortcuts import render, redirect
    from django.utils.timezone import now
    
    from .models import Pressure, Weight
    
    
    class PressureForm(forms.ModelForm):
    
        class Meta:
            model = Pressure
            exclude = ('user', 'timestamp', )
    
    
    class WeightForm(forms.ModelForm):
    
        class Meta:
            model = Weight
            exclude = ('user', 'timestamp', )
    
    
    @login_required
    def submit(request):
        if request.method == 'POST'
            pressure_form = PressureForm(request.POST)
            weight_form = WeightForm(request.POST)
            if all(form.is_valid() for form in [pressure_form, weight_form]):
                record_time = now()
                pressure = pressure_form.save(commit=False)
                pressure.timestamp = record_time
                pressure.user = request.user
                pressure.save()
                weight = weight_form.save(commit=False)
                weight.timestamp = record_time
                weight.user = request.user
                weight.save()
                return redirect('<insert-name-of-success-url>')
        else:
            pressure_form = PressureForm()
            weight_form = WeightForm()
        context = {
            'pressure_form': pressure_form,
            'weight_form': weight_form,
        }
        return render(request, '<insert-template-name>', context)
    

    您不需要表单集或通用视图来处理此问题。这是一个简单而直接的观点。如果您发现自己经常重复这种模式,那么您可能会考虑创建一些视图类来处理这种情况。没有一个内置的泛型会为您执行此操作。

    【讨论】:

    • 在 POST 上接收 'WeightForm' object is not callable。暂时不知道
    • 保存weight_form 缺少对save 的实际调用。我已经进行了编辑。
    【解决方案2】:

    您可以为 2 个模型创建 2 个 ModelFrom。在您的一种形式中,排除“用户”和“时间戳”字段。在模板中,将两种形式的字段放在一个 &lt;form&gt; 标记中。鉴于您应该首先使用“用户”和“时间戳”保存表单,然后将数据从其中放入使用第二种表单创建的实例:

    class PressureForm(forms.ModelForm):
        class Meta:
            model = Pressure
    
    class WeightForm(forms.ModelForm):
        class Meta:
            model = Weight
            exclude = ('user', 'timestamp')
    
    def someview(request):
        if request.method == 'POST':
            pressure_form = PressureForm(request.POST) # user and timestamp is here
            weight_form = WeightForm(request.POST)
    
            if pressure_form.is_valid():
                pressure = pressure_form.save()
    
                if weight_form.is_valid():
                    weight = weight_form.save(commit=False)
                    weight.user = pressure.user
                    weight.timestamp = pressure.timestamp
                    weight.save()
    

    【讨论】:

    • 您是否有机会将第二部分纳入基于类的视图?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 2015-10-15
    • 2019-10-26
    • 2010-12-17
    • 1970-01-01
    相关资源
    最近更新 更多