1

使用 Basti 的答案视图更新

我有一个电话模型(PhoneMixin - 与任何其他模型一起使用)和人:

from django.utils.translation import ugettext_lazy as _
from django.db import models

class PhoneMixin(models.Model):
    TYPES_CHOICES = (
        ('HOME', u'Home'),
        ('WORK', u'Work'),
        ('MOBILE', u'Mobile'),
        ('HOME_FAX', u'Fax (home)'),
        ('WORK_FAX', u'Fax (work)'),
        ('PAGER', u'Pager'),
        ('OTHER', u'Other')
    )
    phone_type = models.CharField(_('Type'), max_length=20, choices=TYPES_CHOICES)
    number = models.CharField(_('Number'), max_length=40)
    comment = models.TextField(_('Comment'), blank=True, null=True)

class Person(models.Model):
    class Meta:
        verbose_name = u'Person'
        verbose_name_plural = u'People'

    name = models.CharField(max_length=255, verbose_name=u'Name')
    email = models.EmailField(max_length=75)

    def __unicode__(self):
        return self.name

class PhonePerson(PhoneMixin):
    belongs_to = models.ForeignKey(Person)

我也有他们的表格:

from django import forms
from models import Person, PhoneMixin

class PersonForm(forms.ModelForm):
    class Meta:
        model = Person

class PhoneForm(forms.ModelForm):
    class Meta:
        model = PhoneMixin

而我唯一的看法是:

from django.forms.formsets import formset_factory
from django.http import HttpResponseRedirect
from django.shortcuts import render
from forms import PhoneForm, PersonForm


def person_insert_view(request):
    PhoneFormset = formset_factory(PhoneForm)

    if request.method == 'POST':  # If the form has been submitted...
        phone_formset = PhoneFormset(request.POST, prefix='phone_formset')
        person_form = PersonForm(request.POST, prefix='person_form')
        if person_form.is_valid():  # All validation rules pass
            person = form.save(commit=False)
            phone_formset = PhoneFormset(request.POST, instance=person)
            if phone_formset.is_valid():
                phone_formset.save()
                person.save()
            return HttpResponseRedirect('/')  # Redirect after POST
        else:
            return render_to_response('function_based_person.html',{
        'person_form': person_form,
        'phone_formset': phone_formset,
    })
    else:
        person_form = PersonForm()
        phone_formset = PhoneFormset(prefix='phone_formset')

    return render(request, 'function_based_person.html', {
        'person_form': person_form,
        'phone_formset': phone_formset,
    })

和 function_based_person.html 模板:

<html>
<body>
<form enctype="multipart/form-data" method="post" action=".">
{% csrf_token %}
{% if person_form.visible_fields %}
    {% for field in person_form.visible_fields %}
    <div class="control-group{% if field.errors %} error{% endif %}">
        <label class="control-label" for="id_{{ field.html_name }}">{{ field.label }}    </label>
        <div class="controls">
            {{ field }}
            {% if field.errors %}
            <span class="help-inline">{% for error in field.errors %}{{ error }}{% endfor %}</span>
            {% endif %}
            {% if field.help_text %}<span class="help-inline">{{ field.help_text }}</span>{% endif %}
        </div>
    </div>
    {% endfor %}

    {% for phone_form in phone_formset %}
      {{phone_form.as_table}}
    {% endfor %}
    <div class="form-actions">
        <button type="submit" class="btn btn-primary">Save</button>
    </div>
{% endif %} 
</form>
</body>
</html>

问题是我想在我的 Person 中至少有一部手机,并且有可能拥有 2 部或更多部,用户想要添加它。

4

1 回答 1

2

ForeignKey 只是指向另一个表中特定行的指针。你的Person模型说的是“每个人都有一部或两部电话。每部电话都存储在另一个名为‘电话’的表中。” 因此,除非您正在做一些复杂的事情,否则您的Person表单会要求您将两个现有电话关联到您的新人员。

(编辑以回应您的评论)。
如果你想做的是拥有多部手机,那么你需要的是一个表单集

您需要做的第一件事是更改哪个表指向哪个:而不是人指向电话,电话应该指向一个人。因此,例如,添加belongs_to = models.ForeignKey(Person)到您的手机型号声明中。

下一步是实际询问您认为的电话。这是表单集的用武之地。在您的视图中,创建一个表单集:

#in views.py
from django.forms.formsets import formset_factory
PhoneFormset = formset_factory(PhoneForm, extras = 1)

if request.method == 'POST':
    phone_formset = PhoneFormset(request.POST, prefix = 'phone_formset')
    person_form = PersonForm(request.POST, prefix='person_form')
    # validate your forms, etc
else:
    person_form = PersonForm()
    phone_formset = PhoneFormset(prefix = 'phone_formset')

添加phone_formset到传递给您的模板的字典,结束渲染它:

# in your template
<form>
{{person_form.as_p}}
{% for phone_form in phone_formset %}
  {{phone_form.as_table}}
{% endfor %}
</form>

您需要做的最后一件事是将每个电话的belongs_to字段设置为提交表单的人员。在您看来,您必须这样做:也许在保存手机之前先保存您的人,获取他们的 pk,设置手机的外键然后保存。

于 2013-07-19T12:09:49.867 回答