表单不保存到带有两个外键的模型 - Django
Form not saving to model with two Foreign Keys - Django
我在将表单保存到具有两个外键的模型时遇到问题:
- 正在提交表单的用户
- 提交的加密货币的当前价格。
表单值似乎通过 AssetView 但未被保存。任何人都可以帮助他们为什么不储蓄。我提供了模型、视图、表单,HTML。
Django 模型
from django.contrib.auth.models import User
class CryptoPrices(models.Model):
symbol = models.CharField(max_length=20)
current_price = models.FloatField(default=0.0)
class CryptoAssets(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
symbol = models.CharField(max_length=20)
amount = models.FloatField(default=0.0)
purchase_price = models.FloatField(default=0.0)
crypto_prices = models.ForeignKey(CryptoPrices, on_delete=models.CASCADE)
Django 视图
from coinprices.forms import AssetForm
class AssetView(TemplateView):
template_name = 'coinprices/my-dashboard.html'
def get(self, request):
form_a = AssetForm(prefix='form_a')
return render(request, self.template_name, {'form_a': form_a})
def post(self, request):
form_a = AssetForm(request.POST, prefix='form_a')
if form_a.is_valid():
post = form_a.cleaned_data
post.save()
form = AssetForm()
args = {'form': form}
return render(request, self.template_name, args)
args = {'form_a': form_a}
return render(request, self.template_name, args)
Django 表单
from coinprices.models import CryptoPrices
tickers = (('BTC', 'BTC'), ('ETH', 'ETH'))
class AssetForm(forms.ModelForm):
symbol = forms.ChoiceField(choices=tickers, required=True, label='')
amount = forms.DecimalField(decimal_places=2, max_digits=20, required=True, label='')
purchase_price = forms.DecimalField(decimal_places=2, max_digits=20, required=True, label='')
class Meta:
model = CryptoAssets
fields = (
'symbol',
'amount',
'purchase_price'
)
HTML
{% extends 'base.html' %}
{% block head %}
<title>My Dashboard</title>
{% endblock %}
{% block body %}
<br>
<div class="container">
<h1>My Dashboard</h1>
<p>
<form method="post">
{% csrf_token %}
{{ form_a.as_p }}
<button type="submit">Submit</button>
</form>
</p>
</div>
{% endblock %}
错误
AttributeError: 'dict' object has no attribute 'save'
让我解释一下错误:
AttributeError: 'dict' object has no attribute 'save'
发生此错误是因为您正在尝试以这种方式保存:
post = form_a.cleaned_data
post.save()
这是错误的,因为 cleaned_data 是一个字典,它包含您的表单的值作为 fieldname:value 对。
正确的做法是:
post = form_a.save()
下一个错误表明字段 crypto_prices 的值是必需的,但您传递的是空值。
django.db.utils.IntegrityError: null value in column "crypto_prices_id" of relation "coinprices_cryptoassets" violates not-null constraint
发生这种情况是因为在您的 AssetForm 表单中您只选择了以下字段:
fields = (
'symbol',
'amount',
'purchase_price'
)
crypto_prices在哪里?该字段在您的 models.py 中定义为必填项:
crypto_prices = models.ForeignKey(CryptoPrices, on_delete=models.CASCADE)
解决方案:您需要在表单中包含字段'crypto_prices',或者在将表单保存到AssetView 之前设置它。像这样:
class资产形式(forms.ModelForm):
symbol = forms.ChoiceField(choices=tickers, required=True, label='')
amount = forms.DecimalField(decimal_places=2, max_digits=20, required=True, label='')
purchase_price = forms.DecimalField(decimal_places=2, max_digits=20, required=True, label='')
class Meta:
model = CryptoAssets
fields = (
'symbol',
'amount',
'purchase_price',
'crypto_prices'
)
或者这样:
class AssetView(TemplateView):
template_name = 'coinprices/my-dashboard.html'
def get(self, request):
form_a = AssetForm(prefix='form_a')
return render(request, self.template_name, {'form_a': form_a})
def post(self, request):
form_a = AssetForm(request.POST, prefix='form_a')
if form_a.is_valid():
post = form_a.save(commit=False)
post.crypto_prices = CryptoPrices.objects.get(id=someid) # this way with object
post.crypto_prices_id = 1 # or this way with a integer
post.save()
form = AssetForm()
args = {'form': form}
return render(request, self.template_name, args)
args = {'form_a': form_a}
return render(request, self.template_name, args)
我在将表单保存到具有两个外键的模型时遇到问题:
- 正在提交表单的用户
- 提交的加密货币的当前价格。
表单值似乎通过 AssetView 但未被保存。任何人都可以帮助他们为什么不储蓄。我提供了模型、视图、表单,HTML。
Django 模型
from django.contrib.auth.models import User
class CryptoPrices(models.Model):
symbol = models.CharField(max_length=20)
current_price = models.FloatField(default=0.0)
class CryptoAssets(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
symbol = models.CharField(max_length=20)
amount = models.FloatField(default=0.0)
purchase_price = models.FloatField(default=0.0)
crypto_prices = models.ForeignKey(CryptoPrices, on_delete=models.CASCADE)
Django 视图
from coinprices.forms import AssetForm
class AssetView(TemplateView):
template_name = 'coinprices/my-dashboard.html'
def get(self, request):
form_a = AssetForm(prefix='form_a')
return render(request, self.template_name, {'form_a': form_a})
def post(self, request):
form_a = AssetForm(request.POST, prefix='form_a')
if form_a.is_valid():
post = form_a.cleaned_data
post.save()
form = AssetForm()
args = {'form': form}
return render(request, self.template_name, args)
args = {'form_a': form_a}
return render(request, self.template_name, args)
Django 表单
from coinprices.models import CryptoPrices
tickers = (('BTC', 'BTC'), ('ETH', 'ETH'))
class AssetForm(forms.ModelForm):
symbol = forms.ChoiceField(choices=tickers, required=True, label='')
amount = forms.DecimalField(decimal_places=2, max_digits=20, required=True, label='')
purchase_price = forms.DecimalField(decimal_places=2, max_digits=20, required=True, label='')
class Meta:
model = CryptoAssets
fields = (
'symbol',
'amount',
'purchase_price'
)
HTML
{% extends 'base.html' %}
{% block head %}
<title>My Dashboard</title>
{% endblock %}
{% block body %}
<br>
<div class="container">
<h1>My Dashboard</h1>
<p>
<form method="post">
{% csrf_token %}
{{ form_a.as_p }}
<button type="submit">Submit</button>
</form>
</p>
</div>
{% endblock %}
错误
AttributeError: 'dict' object has no attribute 'save'
让我解释一下错误:
AttributeError: 'dict' object has no attribute 'save'
发生此错误是因为您正在尝试以这种方式保存:
post = form_a.cleaned_data
post.save()
这是错误的,因为 cleaned_data 是一个字典,它包含您的表单的值作为 fieldname:value 对。
正确的做法是:
post = form_a.save()
下一个错误表明字段 crypto_prices 的值是必需的,但您传递的是空值。
django.db.utils.IntegrityError: null value in column "crypto_prices_id" of relation "coinprices_cryptoassets" violates not-null constraint
发生这种情况是因为在您的 AssetForm 表单中您只选择了以下字段:
fields = (
'symbol',
'amount',
'purchase_price'
)
crypto_prices在哪里?该字段在您的 models.py 中定义为必填项:
crypto_prices = models.ForeignKey(CryptoPrices, on_delete=models.CASCADE)
解决方案:您需要在表单中包含字段'crypto_prices',或者在将表单保存到AssetView 之前设置它。像这样:
class资产形式(forms.ModelForm):
symbol = forms.ChoiceField(choices=tickers, required=True, label='')
amount = forms.DecimalField(decimal_places=2, max_digits=20, required=True, label='')
purchase_price = forms.DecimalField(decimal_places=2, max_digits=20, required=True, label='')
class Meta:
model = CryptoAssets
fields = (
'symbol',
'amount',
'purchase_price',
'crypto_prices'
)
或者这样:
class AssetView(TemplateView):
template_name = 'coinprices/my-dashboard.html'
def get(self, request):
form_a = AssetForm(prefix='form_a')
return render(request, self.template_name, {'form_a': form_a})
def post(self, request):
form_a = AssetForm(request.POST, prefix='form_a')
if form_a.is_valid():
post = form_a.save(commit=False)
post.crypto_prices = CryptoPrices.objects.get(id=someid) # this way with object
post.crypto_prices_id = 1 # or this way with a integer
post.save()
form = AssetForm()
args = {'form': form}
return render(request, self.template_name, args)
args = {'form_a': form_a}
return render(request, self.template_name, args)