我有以下几种型号:
class Profile(models.Model):
verified = models.BooleanField(default=False)
primary_phone = models.OneToOneField('Phone', related_name='is_primary', null=True, blank=True)
class Phone(models.Model):
profile = models.ForeignKey(Profile)
type = models.CharField(choices=PHONE_TYPES, max_length=16)
number = models.CharField(max_length=32)
@property
def is_primary(self):
return profile.primary_phone == self和下列表格:
class PhoneForm(ModelForm):
class Meta:
from accounts.models import Phone
model = Phone
fields = ('type', 'number', )它正在modelformset_factory中使用。
我是这样渲染表单集的:
<div class="span-13 last">
{{ formset.management_form }}
{% for form in Phones %}
<div class="span-2">{{ form.type|add_class:'dropdown' }}</div>
<div class="span-11 last">{{ form.number|add_class:'phone-number' }}</div>
<div class="clearfix"></div>
{% endfor %}
</div>现在,我要做的是在模板中呈现一个单选按钮,以反映Phone模型的Phone属性。通过Phone模型本身或通过Profile.primary_phone确定这种关系有两种方法。但是,我将Phone模型呈现为一个表单集,因此对它的实例进行循环,所以我尝试在PhoneForm字段中包含'is_primary',但是由于它是一个属性,所以它无法工作。
知道怎么做吗?
更新#1:
我使用了jpic方法并尝试将primary呈现为单选按钮:
class PhoneForm(ModelForm):
primary = forms.BooleanField(widget=forms.RadioSelect( choices=((0, 'False'), (1, 'True')) ))
class Meta:
from accounts.models import Phone
model = Phone
fields = ('primary', 'type', 'number', )但是,它为Phone的每个实例显示了两个单选按钮,而我需要它只显示每个实例一个单选按钮。我要用它玩一会儿,看看我能不能让它正确地显示出来。
发布于 2012-03-17 11:13:33
而不是:
class Profile(models.Model):
verified = models.BooleanField(default=False)
primary_phone = models.OneToOneField('Phone', related_name='is_primary', null=True, blank=True)
class Phone(models.Model):
profile = models.ForeignKey(Profile)
type = models.CharField(max_length=16)
number = models.CharField(max_length=32)你应该:
class Profile(models.Model):
verified = models.BooleanField(default=False)
def primary_phone(self):
return self.phone_set.get(primary=True)
class Phone(models.Model):
profile = models.ForeignKey(Profile)
type = models.CharField(max_length=16)
number = models.CharField(max_length=32)
primary = models.BooleanField(default=False)
def save(self, force_insert=False, force_update=False, using=None):
if self.primary:
# clear the primary attribute of other phones of the related profile
self.profile.phone_set.update(primary=False)
self.save(force_insert, force_update, using)这会让你的生活更轻松。
如果您不能进行此更改:电话窗体实际上是许多电话表单的包装器。但是您需要的字段允许编辑Profile.primary_phone。
因此,这样做的一种方法是手动地这样做:
{% for form in Phones %}
<input type="radio" name="primary_phone" checked="{% if form.instance == profile.primary_phone %}checked{% endif %}" value="{{ form.instance.pk }}" />
<!-- snip ... ->但是问题是,由于这个值是{{ form.instance.pk }},所以这个收音机不会有一个空电话表单的值。
另一种方法是向PhoneForm添加一个复选框:
from django import forms
from accounts.models import Phone
class PhoneForm(forms.ModelForm):
primary = forms.BooleanField(required=False, default=False)
class Meta:
model = Phone
fields = ('type', 'number', )我们在这里使用BooleanField,因为对于每个电话表单,主都要设置或不设置。不过,你还是得自己动手:
{% for form in Phones %}
<input type="checkbox" name="{{ form.prefix }}-primary" checked="{% if form.instance == profile.primary_phone %}checked{% endif %}" value="true" />
<!-- snip ... ->但是,您需要javascript来确保在同一时间只检查一台收音机,例如使用jQuery:
$('input[type=checkbox]').change(function() {
$('input[type=checkbox][checked=checked]').attr('checked', '');
$(this).attr('checked', 'checked');
});当然,您应该更新上面示例中的选择器,以确保只影响“主电话”复选框。
最后,要连接复选框,这样的操作可能会奏效:
class PhoneForm(forms.ModelForm):
primary = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
super(PhoneForm, self).__init__(*args, **kwargs)
if self.instance.is_primary:
self.data['primary'] = True
def save(self, *args, **kwargs):
super(PhoneForm, self).save(*args, **kwargs)
if self.cleaned_data['primary']:
self.profile.primary_phone = self
self.profile.save()https://stackoverflow.com/questions/9749420
复制相似问题