Reputation: 1257
I'm trying to add a form on my page that will update a certain field in my DB.
This is what the template looks like:
{% for row in mydb %}
<form action="/myview/{{myslug}}/" method="post" novalidate>
{% csrf_token %}
{% include 'main/includes/bs4_form.html' with form=form3 %}
{{row.firstfield}}
{{row.secondfield}}
<button name="button3" type="submit" class="btn btn-danger style="background-color: red;">CANCEL</button></td>
</form>
{% endfor %}
The for statements is to display each row of the data in my table in a single line. Near each line, there is a submit
button. When this button is clicked, the field secondfield
is updated with the value New Value
, as you can see in my form.
Thi is the part of the view involved:
def myview(request, tvticker):
row = mydb.objects
if request.method == 'POST':
...
if 'button3' in request.POST:
form3 = form = UpdateForm(request.POST)
if form3.is_valid():
profile = form.save(commit=False)
profile.save()
messages.success(request, f"Success")
...
render(request, "main/mytemplate.html",
context={'row': row,})
And here is the form:
class UpdateForm(forms.ModelForm):
SomeField = forms.CharField()
class Meta:
model = MyModel
fields = ("SomeField",)
def save(self, commit=True):
send = super(UpdateForm, self).save(commit=False)
send.secondfield = 'New Value'
if commit:
send.save()
return send
My actual code it's not working, is seems to send a POST request but the secondfield
value is not updated. For example, if i click the submit button of the second record in my template.html, the secondfield
value of that record should be changed from oldvalue
to newvalue
. At the moment, the value is not updated.
Any advice is appreciated, thanks in advance!
Upvotes: 2
Views: 1226
Reputation: 658
you should use
UpdateForm(request.POST, instance=instance)
syntax as said before this post when you have id or slug in your url pattern you can pass it to your view function like this:
def view_function(request, pk, slug)
so no need to pass it in form data
one more problem i see in your code is that you call:
form3.is_valid()
but then try to save
profile = form.save(commit=False)
you validate "form3" but then try to save "form" you must call .is_valid() before you can save a form .is_valid() creates cleaned_data but here you don't validate "form" or save "form3"
try this code below it should solve your problem if not please post all of exception info and traceback
def myview(request, tvticker, slug):
row = mydb.objects
if request.method == 'POST':
if 'button3' in request.POST:
instance = get_object_or_404(MyModel, slug=slug)
form3 = form = UpdateForm(request.POST, instance=instance)
if form3.is_valid():
# here i save form3 instead of form that is not validated
profile = form3.save(commit=False)
profile.save()
render(request, "main/mytemplate.html",
context={'row': row,})
Upvotes: 1
Reputation: 4345
I cannot see how you pass the id (that is the primary key) of the record you want to update to the view. Is it in the post data?
You should remember that the ModelForm constructor has an attribute instance
that should be used to pass an existing object you want to update when calling the save()
method of the ModelForm itself.
You are not using an instance
attribute in the UpdateForm
constructor, so that could be the problem for your record not updating as you expect.
Assuming that the id of the record you want to update is in the POST data with the name pk
you could write something like this:
if 'button3' in request.POST:
instance = MyModel.objects.get(pk=request.POST['pk'])
form3 = form = UpdateForm(request.POST, instance=instance)
if form3.is_valid():
profile = form.save(commit=False)
profile.save()
This is the HTML that you could use to let the id of the record go in the POST data:
{% for row in mydb %}
<form action="/myview/{{myslug}}/" method="post" novalidate>
{% csrf_token %}
<input type="hidden" name="pk" value="{{ row.pk }}">
{% include 'main/includes/bs4_form.html' with form=form3 %}
{{row.firstfield}}
{{row.secondfield}}
<button name="button3" type="submit" class="btn btn-danger style="background-color: red;">CANCEL</button></td>
</form>
{% endfor %}
Upvotes: 1