我创建了一个地址'我的应用程序的许多不同部分使用的模型。每个用户可以拥有多个专属于他们的地址。我创建了另一个类 - ' PersonalDetails' - 属于用户。我希望这个类至少有一个,但最多六个属于用户的地址。
我当前的设置(涉及脆弱的表单)允许这样做,但地址字段是一个“选择”字样。包含当前属于该用户的地址列表的字段。我希望用户能够使用现有地址或创建新地址。我该如何实现这一目标?我试过制作“个人详细信息”。表单使用' AddressForm'但没有任何快乐。
作为额外的奖励,我最初只想渲染一个地址表单,但用户可以选择点击“添加更多地址”。进一步的地址字段。这听起来像是一个表格集的工作,但我不知道它将如何与脆皮一起工作 - 任何帮助都会很棒!
Address_models.py
class Address(models.Model):
# Relations
profile = models.ForeignKey(
Profile,
verbose_name = "user"
)
# Attributes - Mandatory
address_line1 = models.CharField(
max_length = 45,
verbose_name = "Address line 1"
)
city = models.CharField(
max_length = 50,
)
postcode = models.CharField(
max_length = 8,
verbose_name = "Postcode",
help_text = "Enter your postcode",
blank = False,
validators = [RegexValidator(
"[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][A-Z]{2}")]
)
# Attributes - Optional
start_date = models.DateField(
verbose_name = "Start Date",
blank = True,
null = True,
help_text = "Move in date"
)
end_date = models.DateField(
verbose_name = "End Date",
blank = True,
null = True,
help_text = "Move out date"
)
address_line2 = models.CharField(
verbose_name = "Address line 2",
max_length = 45,
blank = True,
null = True
)
county = models.CharField(
verbose_name = "County",
max_length = 40,
blank = True,
null = True
)
PersonalDetails_models.py
class PersonalDetails(models.Model):
# Relations
profile = models.ForeignKey(
Profile,
verbose_name = "user"
)
# Attributes - Mandatory
ni_number = models.CharField(
max_length = 9,
verbose_name = "National Insurance Number",
help_text = "Enter your National Insurance number",
validators = [RegexValidator(
"^[a-zA-Z]{2}[0-9]{6}[A-Z]$")]
)
last_address = models.ForeignKey(
Address
)
# Attributes - Optional
prior_1_address = models.ForeignKey(
Address,
blank = True,
null = True,
related_name = "prior_1_address"
)
prior_2_address = models.ForeignKey(
Address,
blank = True,
null = True,
related_name = "prior_2_address"
)
prior_3_address = models.ForeignKey(
Address,
blank = True,
null = True,
related_name = "prior_3_address"
)
prior_4_address = models.ForeignKey(
Address,
blank = True,
null = True,
related_name = "prior_4_address"
)
prior_5_address = models.ForeignKey(
Address,
blank = True,
null = True,
related_name = "prior_5_address"
)
prior_6_address = models.ForeignKey(
Address,
blank = True,
null = True,
related_name = "prior_6_address"
)
Address_forms.py
class AddressForm(forms.ModelForm):
class Meta:
model = Address
fields = '__all__'
PersonalDetails_forms.py
class PersonalDetailsForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(PersonalDetailsForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_tag = False
class Meta:
model = PersonalDetailsForm
fields = ['ni_number', 'last_address', 'prior_1_address', 'prior_2_address', 'prior_3_address', 'prior_4_address', 'prior_5_address', 'prior_6_address']
答案 0 :(得分:0)
我正在成功使用下面的小部件。
class Formset(LayoutObject):
"""
Layout object. It renders an entire formset, as though it were a Field.
Example::
Formset("attached_files_formset")
"""
template = "%s/formset.html" % TEMPLATE_PACK
def __init__(self, formset_name_in_context, template=None,**kwargs):
self.formset_name_in_context = formset_name_in_context
# crispy_forms/layout.py:302 requires us to have a fields property
self.fields = []
# Overrides class variable with an instance level variable
if template:
self.template = template
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
formset = context[self.formset_name_in_context]
html = ''
return render_to_string(self.template, Context({'wrapper': self,
'formset': formset}))
将此小部件添加到应用程序的某个位置,并像使用其他字段一样使用它。 让我们说你的模块是crispy_layouts
helper_content.append(
crispy_layouts.Formset('address_form')
)
helper = FormHelper()
helper.layout = Layout(
helper_content,
)
address_form是您上下文中的有效formset。 它用 "%S / formset.html"默认情况下,您可以根据需要自定义模板。
我正在使用以下模板和bootstrap3
<div class="formset">
<div class="table-scrollable">
{{ formset.non_form_errors.as_ul }}
<table class="table table-hover">
{% for form in formset.forms %}
{% if forloop.first %}
<thead>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr>
{% for field in form.visible_fields %}
<td> {# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field | as_crispy_field}}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<div class="row">
<div class="col-md-12">
<input type="submit" class="btn btn-primary pull-right" value="Add Row" name="addrow">
</div>
</div>
</div>
</div>
正如您在我的模板中看到的那样,我允许人们在您的视图中添加更多行。如果你的request.POST包含addrow,那么请将你的request.POST复制到post_data,这样它就是可变的。
post_data['addressform-TOTAL_FORMS'] = int(post_data['addressform-TOTAL_FORMS'])+ 1
您基本上会增加TOTAL_FORMS变量并将该表单再次返回给用户。
这是在没有javascript的情况下向formset添加更多行的方法。