2014-01-13 5 views
0

금액을 데이터베이스에 정수로 저장하려고합니다. 편의상 float 필드도 추가했습니다.ModelForm.save를 무시해도 영향을받는 모든 필드가 업데이트되지 않습니다.

# File: models.py 
class Transaction(models.Model): 
    user = models.ForeignKey(User, related_name='transactions') 
    date = models.DateTimeField(default=datetime.now) 
    # transacted btc-amount in satoshi; positive when I bought btc, negative else 
    amount_btc_satoshi = models.IntegerField() 
    # for convenience: transacted btc-amout in units of 1 btc 
    amount_btc = models.FloatField(null=True) 
    # transacted fiat-amount in 1e-5 euros; positive when I sold btc, negative else 
    amount_eur_milicent = models.IntegerField() 
    # for convenience: transacted fiat-amout in units of 1 eur 
    amount_eur = models.FloatField(null=True) 
    # True if I bought bitcoins, False if I sold bitcoins 
    is_bid = models.BooleanField() 
    # effective fiat price per 1 BTC in EUR 
    price_per_btc = models.FloatField() 

편의상 저는 ModelForm 파생물에서 save 메소드를 오버로드했습니다. 자동으로 amount_btcamount_eur에 따라 일부 의존 필드를 업데이트하도록되어 :

# File: forms.py 
class TransactionForm(forms.ModelForm): 
    def clean(self): 
     cleaned_data = super(TransactionForm, self).clean() 
     if cleaned_data['amount_btc'] > 0. and cleaned_data['amount_eur'] > 0.: 
      raise forms.ValidationError('Either BTC amount or fiat amount must be negative.') 
     return cleaned_data 

    def save(self, commit=True, *args, **kwargs): 
     instance = super(TransactionForm, self).save(commit=False, *args, **kwargs) 
     # store input data in integer format 
     instance.amount_btc_satoshi = int(round(self.cleaned_data['amount_btc'] * 1e8)) 
     instance.amount_eur_milicent = int(round(self.cleaned_data['amount_eur'] * 1e5)) 
     # provide convenient amounts 
     instance.amount_btc = instance.amount_btc_satoshi/1e8 
     instance.amount_eur = instance.amount_eur_milicent/1e5 
     instance.is_bid = instance.amount_btc_satoshi > 0 
     instance.price_per_btc = -1. * instance.amount_eur/instance.amount_btc 
     if commit: 
      instance.save() 
     return instance 

    class Meta: 
     model = Transaction 
     fields = ['date', 'amount_btc', 'amount_eur'] 

지금 is_bid 예상과 다른 dependend 필드가 제대로 설정으로 새로운 transaction 작품을 추가. 그러나 기존 항목을 편집하면 하나의 필드 만 업데이트됩니다. 예 :

# File: views.py 
@login_required 
def transaction_add(request): 
    form = TransactionForm(request.POST) 
    if form.is_valid(): 
     transaction = form.save(commit=False) 
     transaction.user = request.user 
     transaction.save() 
    else: 
     messages.error(request, ';'.join('{}: {}'.format(key, value) for key, value in form.errors.items())) 
    return redirect(request.POST['next']) 

@login_required 
def transaction_edit(request, id): 
    transaction = Transaction.objects.get(id=id) 
    form = TransactionForm(request.POST, instance=transaction) 
    if form.is_valid(): 
     transaction.save() 
    else: 
     messages.error(request, ';'.join('{}: {}'.format(key, value) for key, value in form.errors.items())) 
    return redirect(request.POST['next']) 

내가 instance.save(update_fields=None)을 시도했지만 전혀 영향을주지 않았다 둘 price_per_btcamount_eur_milicent (아래 참조) amount_eur 경우에도 변경되지 않습니다. 아이디어?

는 트랜잭션 인스턴스가 이런 식으로 수정되지 않습니다

답변

1

, 당신은()를 명시 적으로 form.save를 호출해야합니다 당신은 새로운 객체를 생성하지 않습니다

transaction = Transaction.objects.get(id=id) 
form = TransactionForm(request.POST, instance=transaction) 
if form.is_valid(): 
    form.save() 

(형태가 실제로 변경된 데이터를 포함 원인) 객체 기본 키가 변경되지 않았기 때문에 기존 객체를 편집하십시오.

+0

나는 어리 석습니다. 복사 및 붙여 넣기 오류를 추가 메서드에서 것 같아요. 감사! –