2012-03-17 15 views
0

ように2つのモデル間の関係をレンダリングDjangoはラジオボタン、私は次のモデルを持っている

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モデルのis_primary性質を反映するために、テンプレートのラジオボタンをレンダリングすることです。この関係を決定するには、Phoneモデル自体またはProfile.primary_phoneを介して2つの方法があります。しかし、私はモデルをフォームセットとしてレンダリングしていますので、そのインスタンスをループして、'is_primary'PhoneFormフィールドに含めることを試みましたが、それはプロパティなので動作しませんでした。

どうすればいいですか?

更新#1:

Iは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',) 

Iが必要ながらしかし、Phoneのインスタンスごとに2つのラジオボタンを示しますインスタンスごとに1つのラジオボタンのみを表示します。私はしばらくそれを試してみて、それを正しく表示できるかどうかを見ます。

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) 

あなたが持っている必要があります:代わりの

答えて

2

あなたの人生を容易にするだろう

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にチェックボックスを追加することです:各携帯電話のフォームのために、主が設定またはないことがあるので、私たちはここのBooleanFieldを使用している

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',) 

{% for form in Phones %} 
    <input type="checkbox" name="{{ form.prefix }}-primary" checked="{% if form.instance == profile.primary_phone %}checked{% endif %}" value="true" /> 
    <!-- snip ... -> 

をしかし、その後、あなたはJavascriptを一つだけのラジオは、例えば一度にチェックされていることを確認する必要があります。しかし、まだ、あなたはそれを自分でレンダリングする必要がありますwith 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() 
+0

これは、作業を行い、それが 'だとき、空のために' Phone'フォームが[値]は 'NONE'あるので、私はそれらを処理することができます彼らが値を持っているかどうかを確認してください。私はあまりカスタムコード/より多くのdjangoスタイルの方法を望んでいた。 – abstractpaper

+0

私はあなたの最初のアプローチが好きです!私はモデルを変更しても問題ありません。しかし、各 'Phone'インスタンスのラジオボタンをレンダリングしようとすると、インスタンスごとに2つのラジオボタン(true/false)が表示されます。私はあなたが何を意味するかを一分で自分の投稿を編集します。 – abstractpaper

関連する問題