0

After logging in, my users complete a four forms and a pdf is generated containing the data from the forms. I can successfully do this and save the pdf, but dont know how to attach the generated pdf to the user. I usually save form data in an if request.method == 'POST': statement in the view.py file, but the pdf isnt being sent through POST, it is instead generated and saved within a function called after if request.method == 'POST': so I guess i need a way to attach it to the users pdf model within that function?

Also, the questionnaire is quite large so I broke it into four separate forms and four seperate models each with a one-to-one relationship with the user. Is this good practice or should I create one large model and break it up using four separate forms?

utils.py

def generate_questionnaire_pdf(request):
    # get user
    user = request.user

    # create pdf
    pdf = SimpleDocTemplate(settings.MEDIA_ROOT+'\pdfs\\questionnaire_pdfs\\user_%s.pdf' %user.id)

[..cont..]

pdf.build(elems, onFirstPage=partial(pageSetup, title=title, user=user), onLaterPages=pageSetup)

form.py

class QuestionnairePdfForm(forms.ModelForm):

    class Meta:
        model = QuestionnairePdf
        fields = ['questionnaire_pdf']

model.py

class QuestionnairePdf(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    questionnaire_pdf = models.FileField(upload_to='pdfs\\questionnaire_pdfs')

view.py

def final_question(request):
    if request.method == 'POST':
        form = FinalQuestionForm(request.POST, request.FILES, instance=request.user.finalquestion)

        if form.is_valid():
            form.save()

            # generate pdf containing all answers to questionnaire
            utils.generate_questionnaire_pdf(request)

Thank you.

horse
  • 479
  • 7
  • 25
  • 1
    I guess you can go with the model you currently have(with the information you given). And I've some suggestions, If you don't want to pdf to be generated immediately, go for a background task(celery, django-q, apscheduler), Other wise you can send the response immediately using FileResponse(https://docs.djangoproject.com/en/3.0/howto/outputting-pdf/). Also you can use a post-save signal on the last model, and generate a pdf. – Jisson May 26 '20 at 02:34
  • Thank you. If I send a response immediately using FileResponse, how would I then save it please? Sorry, my understanding is very low – horse May 26 '20 at 02:54
  • The the client( browser) will show a pop-up to save the pdf, when it got a response – Jisson May 26 '20 at 02:56
  • Sample FileResponse: return FileResponse(buffer, as_attachment=True, filename='hello.pdf'). check it here https://docs.djangoproject.com/en/3.0/howto/outputting-pdf/ – Jisson May 26 '20 at 02:56
  • Oh, I dont want to allow the user to download the file, just save the location to their database – horse May 26 '20 at 05:01
  • save your pdf file in the system in media folder, and keep the path of the file in your database, Use a FileField in your model. – Jisson May 26 '20 at 05:07
  • Ah okay. To save the path to the file in my db should I return it to my view after calling ```generate_questionnaire_pdf()``` like ```return filename```. Then in my view something like ```pdf = EnrolmentPdf() pdf.enrolment_pdf= filename``` ? – horse May 26 '20 at 05:11
  • you don't need to save the path to db, Django FileFiled will do all for you , https://stackoverflow.com/questions/7514964/django-how-to-create-a-file-and-save-it-to-a-models-filefield – Jisson May 26 '20 at 08:41

0 Answers0