Reputation: 2570
Every row of the table has a button with the pk of the element. Using the button should fill the form with the states of the entry.
I think I have a problem with the renderer, as it clears my form but I'm not sure how to fix this. I would like to achieve this without the use of AJAX if possible.
HTML:
<form action="" method="POST">
{% csrf_token %}
<input type="hidden" name="pk" value="{{ post.pk }}">
<input class="btn btn-default btn-danger" name="update" type="submit" value="Ändern"/>
</form>
views.py:
from django.shortcuts import render
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from .forms import NameForm
from .models import Eintrag
@login_required()
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST' and 'add' in request.POST:
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
#Eintrag.objects.filter(Name=request.user).delete()
eintrag = form.save(commit=False)
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
eintrag.Name = request.user # Set the user object here
eintrag.pub_date = timezone.now() # Set the user object here
eintrag.save()
return HttpResponseRedirect(request.path) # generate an empty form
if request.method == 'POST' and 'delete' in request.POST:
Eintrag.objects.filter(id=request.POST['pk']).delete()
return HttpResponseRedirect(request.path)
if request.method == 'POST' and 'update' in request.POST:
form = NameForm()
form.fields['Anmeldung'] = Eintrag.objects.get(id=request.POST['pk']).Anmeldung
form.fields['Essen'] = Eintrag.objects.get(id=request.POST['pk']).Essen
form.fields['Email'] = Eintrag.objects.get(id=request.POST['pk']).Email
return HttpResponseRedirect(request.path) # this emptys my form
#posts = Eintrag.objects.filter(Name=request.user)
#return render(request, 'form/name.html', {'form': form, 'posts': posts}) # I get an AttributError with this
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
posts = Eintrag.objects.filter(Name=request.user)
return render(request, 'form/name.html', {'form': form, 'posts': posts})
forms.py
from django import forms
from .models import Eintrag
class NameForm(forms.ModelForm):
class Meta:
model = Eintrag
fields = ['Anmeldung', 'Essen','Email']
models.py
from django.db import models
Anmeldung = (
('1', 'Ja'),
('2', 'Nein'),
('3', 'Noch nicht entschieden'),
)
Essen = (
('1', 'Fleisch'),
('2', 'Fisch'),
('3', 'Vegetarisch'),
)
class Eintrag(models.Model):
Name = models.CharField(max_length=200)
Anmeldung = models.CharField(
max_length=2,
choices=Anmeldung)
Essen = models.CharField(
max_length=2,
choices=Essen)
Email = models.EmailField()
pub_date = models.DateTimeField('date published')
With my try to just create posts and render after the POST, I'm getting some error. like this:
Exception Type: AttributeError
Exception Value:
'str' object has no attribute 'get_bound_field'
Thanks for your help.
form.['field'] should set the current state of the form to the selected data, I tried form['field'].initial too.
Full Traceback with:
posts = Eintrag.objects.filter(Name=request.user)
return render(request, 'form/name.html', {'form': form, 'posts': posts})
Template error:
In template C:\Users\basti\Desktop\hochzeit\form\templates\form\name.html, error at line 35
'str' object has no attribute 'get_bound_field'
25 : <div class="row">
26 :
27 :
28 : <div class="col-sm-10">
29 :
30 : <div class='container-fluid'>
31 : <br><br>
32 :
33 : <form action="" method="post">
34 : {% csrf_token %}
35 : {{ form }}
36 : <input type="submit" name="add" value="Update" />
37 : </form>
38 :
39 : {% include "form/post_list.html" %}
40 :
41 : </div>
42 : </div>
43 : </div>
44 :
45 : </body>
Traceback:
File "C:\Python35\lib\site-packages\django\core\handlers\exception.py" in inner
35. response = get_response(request)
File "C:\Python35\lib\site-packages\django\core\handlers\base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "C:\Python35\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python35\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
21. return view_func(request, *args, **kwargs)
File "C:\Users\basti\Desktop\hochzeit\form\views.py" in get_name
41. return render(request, 'form/name.html', {'form': form, 'posts': posts})
File "C:\Python35\lib\site-packages\django\shortcuts.py" in render
36. content = loader.render_to_string(template_name, context, request, using=using)
File "C:\Python35\lib\site-packages\django\template\loader.py" in render_to_string
62. return template.render(context, request)
File "C:\Python35\lib\site-packages\django\template\backends\django.py" in render
61. return self.template.render(context)
File "C:\Python35\lib\site-packages\django\template\base.py" in render
175. return self._render(context)
File "C:\Python35\lib\site-packages\django\template\base.py" in _render
167. return self.nodelist.render(context)
File "C:\Python35\lib\site-packages\django\template\base.py" in render
943. bit = node.render_annotated(context)
File "C:\Python35\lib\site-packages\django\template\base.py" in render_annotated
910. return self.render(context)
File "C:\Python35\lib\site-packages\django\template\base.py" in render
999. return render_value_in_context(output, context)
File "C:\Python35\lib\site-packages\django\template\base.py" in render_value_in_context
978. value = str(value)
File "C:\Python35\lib\site-packages\django\utils\html.py" in <lambda>
380. klass.__str__ = lambda self: mark_safe(klass_str(self))
File "C:\Python35\lib\site-packages\django\forms\forms.py" in __str__
136. return self.as_table()
File "C:\Python35\lib\site-packages\django\forms\forms.py" in as_table
279. errors_on_separate_row=False)
File "C:\Python35\lib\site-packages\django\forms\forms.py" in _html_output
201. bf = self[name]
File "C:\Python35\lib\site-packages\django\forms\forms.py" in __getitem__
167. self._bound_fields_cache[name] = field.get_bound_field(self, name)
Exception Type: AttributeError at /form/
Exception Value: 'str' object has no attribute 'get_bound_field'
Upvotes: 1
Views: 1097
Reputation: 599600
As I said in the comment, that's not how you assign values to a form field. What you've done is to completely replace the field object in the form's dictionary with the value from the model, which isn't at all what you want to do.
With a normal form, you could pass this data in via the initial
dict when creating the form instance. But this is a ModelForm, which is specifically designed to take values from models; you should just pass the model instance itself via the instance
argument:
eintrag = Eintrag.objects.get(id=request.POST['pk'])
form = NameForm(instance=eintrag)
posts = Eintrag.objects.filter(Name=request.user)
return render(request, 'form/name.html', {'form': form, 'posts': posts})
Upvotes: 1