2012-03-14 6 views
1

私はDjangoとWeb開発の概念全体でかなり新しくなっています。私はJavaとC++のみを使っていましたが、私の大学ではWeb開発者として働いていました。私は現在、フォームを実装しようとしています - (http://albedo.csrcdev.com/pages/submit)。私のモデルでは、アルベドと呼ばれる私のフォームに現れないフィールドがもう1つあります。アルベドは、sum(outgoing1、outgoing2、outgoing3)/ sum(incoming1、incoming2、incoming3)によって計算されます。だから私の質問は、どのようにどこからデータベースからそれらの変数を取り、新しい計算値をAlbedoに割り当てるかです。Djangoフォーム、フォームから新しい値を計算してモデルに割り当てます

私の同僚は私のフォームにModelFormを使用して、views.pyでそれをやってみるように言いましたが、今ここで私は座っていて寂しいです。事前に:(

おかげで、

デビッド

views.py

@login_requried 
def submit(request): 
if request.method =='POST': 
    form = DataEntryForm(request.POST) 
    model = DataEntry() 
    if form.is_valid(): 
     form.save() 
     return HttpResponseRedirect('/map/rebuild/')            


else:                       
    form = DataEntryForm()                   

return render_to_response(
     'pages/submit.html', { 'form': form }, 
     context_instance=RequestContext(request)) 
+0

あなたのviews.pyコードの一部を投稿することができます – Mayank

答えて

3
form = DataEntryForm(request.POST) 
if form.is_valid(): 
    instance = form.save(commit=False) 
    instance.albedo = do_calc(instance.whatever0, instance.whatever1) 
    instance.save() 
    return HttpResponseRedirect('/map/rebuild/') 

手動model = DataEntry()をインスタンス化する必要はありません注 - DataEntryFormModelFormサブクラスである場合は、.save()を呼び出すときに、それがモデルを作成します。

DataEntry.update_albedo()メソッドなどで計算をカプセル化することをお勧めします。ビュー自体で計算を行う代わりに、instance.save()の前にそれを呼び出すことになります。

+0

応答をいただきありがとうございます、それは簡単で、仕事を完了させるでしょう、これはおそらく最善の方法です。 – dajee

0

可能な解決策はpresave signalのフィールドを更新することである。このアプローチでは:。

  • あなたアルベドフィールドはモデルを保存する前に更新されます。
  • 保存をコミットすることはできません。save(commit=False)。これにより、データベースへの変更をコミットせずにフィールドが更新されます。

Iはdjango signals docからtakedサンプルを投稿:

from django.db.models.signals import pre_save 
from django.dispatch import receiver 
from myapp.models import MyModel 

@receiver(pre_save, sender=MyModel) 
def my_handler(sender, **kwargs): 
    sender.Albedo = sender.outgoing1 + ... 
2

IはModelFormsave方法からこの値を割り当てることになります。

すぎて、albedoは、モデル内のフィールドの名前であると仮定すると:

Class MyModelForm(forms.ModelForm): 
    class Meta: 
     model = MyModel 
     exclude = ('albedo') 

    def calculate_albedo(outgoing1, outgoing2, outgoing3, incoming1, 
              incoming2, incoming3): 
     return sum([outgoing1, outgoing2, outgoing3])/sum([incoming1, 
         incoming2, incoming3]) 

    def save(self, commit=True): 
     form_data = self.cleaned_data 
     self.instance.someval1 = form_data['someval1'] 
     self.instance.someval2 = form_data['someval2'] 
     self.instance.someval3 = form_data['someval3'] 
     self.instance.albedo = self.calculate_albedo(
        form_data['outoing1'], form_data['outoing2'], 
        form_data['outoing3'], form_data['incoming1'], 
        form_data['incoming2'], form_data['incoming3']) 
     return super(MyModelForm, self).save(commit) 

また、Albedoはクラス名でない場合は、小文字を使用する必要があります。それはPythonic conventionです。

+0

おそらく 'self.instance.user.save()'ブロックを失いたい... – AdamKG

+0

ああ、それをキャッチするためにありがとう。 – bennylope

関連する問題