как сохранить 3 формы одной модели в django? - PullRequest
0 голосов
/ 15 января 2020

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 частей. Мне нужно сделать в указанном порядке c, со второй формы, требующей только загрузки изображения. Мой план состоит в том, чтобы захватить обязательные поля и временно хранить в сессиях. когда форма сохранена, я намерен удалить сеансы (сейчас это не важно)

В текущем сценарии, когда третья форма обрабатывается / сохраняется. содержимое первой формы, третьей формы и имени изображения из второй формы будет сохранено. однако изображение не загружается в нужную папку.

1 Ответ

1 голос
/ 15 января 2020

Я не знаю, возможно ли сохранить файл в сеансе с помощью какой-то хитрости. Обходной путь, который я вижу, состоит в том, чтобы сохранить файл в требуемом месте назначения во втором представлении и сохранить путь к этому файлу в сеансе. Затем используйте этот сохраненный путь для создания объекта в третьем представлении.

Итак, создайте небольшую функцию для обработки загрузки

def handle_uploaded_file(f, upload_to):
    with open(upload_to, 'wb') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

, а затем используйте ее для сохранения файла во втором view

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})

Я думаю, что назначение пути к полю вашего изображения должно работать, так что вам не нужно менять третий вид.

Однако помните о двух вещах:

  1. handle_uploaded_file ожидает, что существует правильная папка назначения. Если вы не можете гарантировать это, вы должны добавить проверку для папки и создать ее, если она не существует

  2. handle_uploaded_file будет перезаписывать существующие файлы с тем же именем. Если этого следует избегать, проверьте существующие файлы перед записью и измените имя файла соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...