I have a model:
class Cost(models.Model):
project = models.ForeignKey(Project)
cost = models.FloatField()
date = models.DateField()
For the model I created a ModelForm
class:
class CostForm(ModelForm):
class Meta:
model = Cost
fields = ['date', 'cost']
with view.py
:
def cost(request, offset):
if request.method == 'POST':
# NOTE: How to save the data in DB?
return HttpResponseRedirect('/')
else:
form = CostForm()
and next template:
<form action="/cost/{{ project }}/" method="post" accept-charset="utf-8">
<label for="date">Date:</label><input type="text" name="date" value={{ current_date }} id="date" />
<label for="cost">Cost:</label><input type="text" name="cost" value="0" id="cost" />
<p><input type="submit" value="Add"></p>
</form>
How I can save the data from the form to the database?
model.py
contains
class Project(models.Model):
title = models.CharField(max_length=150)
url = models.URLField()
manager = models.ForeignKey(User)
timestamp = models.DateTimeField()
I tried to implement the solution in a next way (note: offset = project name):
def cost(request, offset):
if request.method == 'POST':
form = CostForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.project = Project.objects.filter(title=offset)
instance.date = request.date
instance.cost = request.cost
instance.save()
return HttpResponseRedirect('/')
else:
form = CostForm()
But it does not work :(
Saving objects. To save an object back to the database, call save() : Model.
Using Form in a View In Django, the request object passed as parameter to your view has an attribute called "method" where the type of the request is set, and all data passed via POST can be accessed via the request. POST dictionary. The view will display the result of the login form posted through the loggedin.
save() , django will save the current object state to record. So if some changes happens between get() and save() by some other process, then those changes will be lost.
A couple things don't look right:
Project.objects.filter()
will return a queryset. Use Project.objects.get()
instead... it will return just a single Project
object
You wont need to explicitly set the cost and date, that will be handled by your instance=form.save(commit=False)
You aren't using the form in your template...
Try this:
Template:
<form action="/cost/{{ project }}/" method="post" accept-charset="utf-8">
{{form.as_p}}
<p><input type="submit" value="Add"></p>
</form>
View:
def cost(request, offset):
if request.method == 'POST':
form = CostForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.project = Project.objects.get(title=offset)
instance.save()
return HttpResponseRedirect('/')
else:
form = CostForm()
render_to_response('path/to/template.html',{'form':form},context_instance=RequestContext(request))
Also, I think you will need to add blank=True
to your models.ForeignKey(Project)
in the Cost
model. That will allow your ModelForm to validate.
I found the solution. Rewrote view.py
as follows:
def cost(request, offset):
if request.method == 'POST':
project = Project.objects.get(title=offset)
date = request.POST.get('date', '')
cost = request.POST.get('cost', '')
cost_obj = Cost(project=project, date=date, cost=cost)
cost_obj.save()
return HttpResponseRedirect('/')
The rest of the code has not changed.
I did it this way:
def save_model(self, request, obj, form, change):
obj.save()
To modify something, do it through:
obj.xyz = 'something'
obj.save()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With