0

I am trying to create a form that allows current logged in user to submit data. The form comprises of the field - amount, rate(interest), timestamp(automatically picked up), and currently logged in user.

Data is not passing into the database and giving an error like - The view investors.views.InvestView didn't return an HttpResponse object. It returned None instead.

views.py

def InvestView(request):
    if request.method == 'GET':
        investment_form = InvestorsForm(request.user)
        context = {'investment_form': investment_form}
        return render(request, 'investors/form.html', context)
    if request.method == 'POST':
        investment_form = InvestorsForm(request.POST or None, instance=request.user)
        if investment_form.is_valid():
            amount = investment_form.cleaned_data['amount']
            interest = investment_form.cleaned_data['rate']
            saving = investment_form.save(commit=False)

            # Passing Logged in user
            investor = request.user
            print(investor)
            saving.investor = request.user.id
            saving.save()
            messages.success(request, f'New Investment Done!')
            return redirect('/myinvest/')

forms.py

class InvestorsForm(forms.ModelForm):

    class Meta :
        model = Investment
        fields = ['amount', 'rate']

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(InvestorsForm, self).__init__(*args, **kwargs)

models.py

class Investor(models.Model):  
    name = models.CharField(max_length=99) 
    user = models.ForeignKey(User, on_delete=models.CASCADE)


    def __str__(self):
        return self.name


class Investment(models.Model):
    amount = models.FloatField(blank=False)
    rate = models.FloatField(blank=False)
    timestamp = models.DateField(default=datetime.now)
    investor = models.ForeignKey(Investor, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.investor)

Data must be stored into the database and redirect the page to myinvest section simultaneously.

Manish
  • 501
  • 4
  • 11

3 Answers3

3

This issue has nothing to do with adding the user. It is because you do nothing in case the validation fails.

You should turn your function the other way round so that the render is hit in all cases.

def InvestView(request):
    if request.method == 'POST':
        investment_form = InvestorsForm(request.POST)
        if investment_form.is_valid():
            saving = investment_form.save(commit=False)
            saving.investor.user = request.user
            saving.save()
            messages.success(request, f'New Investment Done!')
            return redirect('/myinvest/')
    else:
        investment_form = InvestorsForm()
    context = {'investment_form': investment_form}
    return render(request, 'investors/form.html', context)

Note the indentation.

The actual failure to validate is because you have changed the signature of the form to accept a user parameter first, instead of the expected data. However it is not clear why you have done this as you do not use that value, but instead set the user in the view. You should remove that __init__ method.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
0

You need to replace saving.investor = request.user.id with saving.investor.user = request.user.

cagrias
  • 1,847
  • 3
  • 13
  • 24
  • same issues. Please check forms.py or models.py if you find any bug there. I am not able to recognize. You can suggest any other method – Manish Jul 05 '19 at 07:51
0

Another error: your form's __init__ method takes a user as its first argument:

def __init__(self, user, *args, **kwargs):

In the case of a GET request, you pass it correctly:

investment_form = InvestorsForm(request.user)

But then with a POST request, you forget it:

investment_form = InvestorsForm(request.POST or None, instance=request.user)

Passing request.user as the first argument there as well should help.

RemcoGerlich
  • 30,470
  • 6
  • 61
  • 79