如何在 Django 中保存一个模型的 3 种形式?
how to save 3 forms of one model in django?
models.py
class Campaign(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
# this is many to one relationship, on_deleting user, profile will also be deleted
funds_for = models.CharField(max_length=200)
campaign_title = models.CharField(max_length=200, blank=True)
amount_required = models.IntegerField(null=True, blank=True)
campaign_image = models.ImageField(default="default_campaign.png",upload_to="campaign_pictures")
forms.py
class RaiseFundsFrom1(forms.ModelForm):
class Meta:
model = Campaign
fields = ['funds_for']
class RaiseFundsFrom2(forms.ModelForm):
class Meta:
model = Campaign
fields = ['campaign_image']
class RaiseFundsFrom3(forms.ModelForm):
class Meta:
model = Campaign
fields = ['campaign_title','amount_required']
views.py
@login_required
def raise_funds_medical_1(request):
if request.method == 'POST':
form = RaiseFundsFrom1(request.POST)
if form.is_valid():
request.session['funds_for'] = form.cleaned_data.get('funds_for')
return redirect('funds:raise_funds_medical_2')
else:
form = RaiseFundsFrom1(instance=request.user)
return render(request,'funds/raise_funds_medical_1.html',{'form':form})
@login_required
def raise_funds_medical_2(request):
if request.method == 'POST':
form = RaiseFundsFrom2(request.POST, request.FILES or None)
if form.is_valid():
f = request.FILES['campaign_image']
request.session['campaign_image'] = f.name
return redirect('funds:raise_funds_medical_3')
else:
form = RaiseFundsFrom2(instance=request.user)
return render(request,'funds/raise_funds_medical_2.html',{'form':form})
@login_required
def raise_funds_medical_3(request):
if request.method == 'POST':
form = RaiseFundsFrom3(request.POST)
if form.is_valid():
request.session['campaign_title '] = form.cleaned_data.get('campaign_title')
request.session['amount_required '] = form.cleaned_data.get('amount_required')
c = Campaign()
c.funds_for = request.session['funds_for']
c.campaign_image = request.session['campaign_image']
c.campaign_title = request.session['campaign_title']
c.amount_required = request.session['amount_required']
c.save()
return redirect('core:landing_page')
else:
form = RaiseFundsFrom3(instance=request.user)
return render(request,'funds/raise_funds_medical_3.html',{'form':form})
我需要分 3 个部分获取广告系列模型的详细信息。我需要按特定顺序执行,第二个表格只需要上传图片。我的计划是捕获所需的字段并临时存储在会话中。保存表格后,我打算删除会话(现在不重要)
当前场景下,当第三形态为processed/saved。第一种形式的内容,第三种形式和第二种形式的图像名称被保存。但是,图像不会上传到所需的文件夹。
我不知道是否可以通过一些技巧将文件保存到会话中。我看到的一种解决方法是将文件保存在第二个视图中所需的目标位置,并在会话中保存该文件的路径。然后使用这个保存的路径在第三个视图中创建对象。
因此,创建一个小函数来处理上传
def handle_uploaded_file(f, upload_to):
with open(upload_to, 'wb') as destination:
for chunk in f.chunks():
destination.write(chunk)
然后使用它在您的第二个视图中保存文件
def raise_funds_medical_2(request):
if request.method == 'POST':
form = RaiseFundsFrom2(request.POST, request.FILES or None)
if form.is_valid():
f = request.FILES['campaign_image']
f_path_rel = os.path.join("campaign_pictures", f.name)
f_path = os.path.join(settings.MEDIA_ROOT, f_path_rel)
handle_uploaded_file(f, f_path)
request.session['campaign_image'] = f_path_rel
return redirect('raise_funds_medical_3')
else:
form = RaiseFundsFrom2(instance=request.user)
return render(request,'funds/raise_funds_medical_2.html',{'form':form})
我认为将路径分配给您的图像字段应该可行,这样您就不需要更改您的第三个视图。
但是,请注意两件事:
handle_uploaded_file
期望正确的目标文件夹
存在。如果你不能保证这一点,你应该为
文件夹,如果不存在则创建它
handle_uploaded_file
将用相同的文件覆盖现有文件
姓名。如果应该避免这种情况,请先检查现有文件
相应地写入和修改文件名。
models.py
class Campaign(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
# this is many to one relationship, on_deleting user, profile will also be deleted
funds_for = models.CharField(max_length=200)
campaign_title = models.CharField(max_length=200, blank=True)
amount_required = models.IntegerField(null=True, blank=True)
campaign_image = models.ImageField(default="default_campaign.png",upload_to="campaign_pictures")
forms.py
class RaiseFundsFrom1(forms.ModelForm):
class Meta:
model = Campaign
fields = ['funds_for']
class RaiseFundsFrom2(forms.ModelForm):
class Meta:
model = Campaign
fields = ['campaign_image']
class RaiseFundsFrom3(forms.ModelForm):
class Meta:
model = Campaign
fields = ['campaign_title','amount_required']
views.py
@login_required
def raise_funds_medical_1(request):
if request.method == 'POST':
form = RaiseFundsFrom1(request.POST)
if form.is_valid():
request.session['funds_for'] = form.cleaned_data.get('funds_for')
return redirect('funds:raise_funds_medical_2')
else:
form = RaiseFundsFrom1(instance=request.user)
return render(request,'funds/raise_funds_medical_1.html',{'form':form})
@login_required
def raise_funds_medical_2(request):
if request.method == 'POST':
form = RaiseFundsFrom2(request.POST, request.FILES or None)
if form.is_valid():
f = request.FILES['campaign_image']
request.session['campaign_image'] = f.name
return redirect('funds:raise_funds_medical_3')
else:
form = RaiseFundsFrom2(instance=request.user)
return render(request,'funds/raise_funds_medical_2.html',{'form':form})
@login_required
def raise_funds_medical_3(request):
if request.method == 'POST':
form = RaiseFundsFrom3(request.POST)
if form.is_valid():
request.session['campaign_title '] = form.cleaned_data.get('campaign_title')
request.session['amount_required '] = form.cleaned_data.get('amount_required')
c = Campaign()
c.funds_for = request.session['funds_for']
c.campaign_image = request.session['campaign_image']
c.campaign_title = request.session['campaign_title']
c.amount_required = request.session['amount_required']
c.save()
return redirect('core:landing_page')
else:
form = RaiseFundsFrom3(instance=request.user)
return render(request,'funds/raise_funds_medical_3.html',{'form':form})
我需要分 3 个部分获取广告系列模型的详细信息。我需要按特定顺序执行,第二个表格只需要上传图片。我的计划是捕获所需的字段并临时存储在会话中。保存表格后,我打算删除会话(现在不重要)
当前场景下,当第三形态为processed/saved。第一种形式的内容,第三种形式和第二种形式的图像名称被保存。但是,图像不会上传到所需的文件夹。
我不知道是否可以通过一些技巧将文件保存到会话中。我看到的一种解决方法是将文件保存在第二个视图中所需的目标位置,并在会话中保存该文件的路径。然后使用这个保存的路径在第三个视图中创建对象。
因此,创建一个小函数来处理上传
def handle_uploaded_file(f, upload_to):
with open(upload_to, 'wb') as destination:
for chunk in f.chunks():
destination.write(chunk)
然后使用它在您的第二个视图中保存文件
def raise_funds_medical_2(request):
if request.method == 'POST':
form = RaiseFundsFrom2(request.POST, request.FILES or None)
if form.is_valid():
f = request.FILES['campaign_image']
f_path_rel = os.path.join("campaign_pictures", f.name)
f_path = os.path.join(settings.MEDIA_ROOT, f_path_rel)
handle_uploaded_file(f, f_path)
request.session['campaign_image'] = f_path_rel
return redirect('raise_funds_medical_3')
else:
form = RaiseFundsFrom2(instance=request.user)
return render(request,'funds/raise_funds_medical_2.html',{'form':form})
我认为将路径分配给您的图像字段应该可行,这样您就不需要更改您的第三个视图。
但是,请注意两件事:
handle_uploaded_file
期望正确的目标文件夹 存在。如果你不能保证这一点,你应该为 文件夹,如果不存在则创建它handle_uploaded_file
将用相同的文件覆盖现有文件 姓名。如果应该避免这种情况,请先检查现有文件 相应地写入和修改文件名。