My path looks like so:
path('edit/<str:entry_name>/', views.edit, name='edit').
I want to access this path through a form like so:
<form action="{% url 'edit' entry_name=entry_title %}" method="get">
{% csrf_token %}
<input type="hidden" name="title" value="{{ entry_title }}">
<input type="hidden" name="content" value="{{ entry_content }}">
<input type="submit" value="Edit">
</form>
But then I get this error: Reverse for 'edit' with keyword arguments '{'entry_name': ''}' not found. 1 pattern(s) tried: ['edit/(?P<entry_name>[^/]+)/\\Z'].
It seems like entry_name is empty, but I use the entry_name parameter elsewhere on the page and it works fine.
{% block title %}
{{ entry_title }}
{% endblock title %}
is not empty, since I can see the titel on the tab-title.
EDIT:
Here are the views:
To access the entry page where the form is located:
def entry(request, title):
entry = util.get_entry(title)
if entry is None:
return render(request, "encyclopedia/error.html", {
"error_name": "Not Found",
"error_message": f"{title} page Not Found"
})
return render(request, "encyclopedia/entry.html", {
"entry_title": title,
"entry_content": markdown2.markdown(entry)
})
The edit view:
def edit(request, entry_name):
if request.method == "POST":
query_dict = request.POST
new_entry_name = entry_name
content = query_dict.get("content")
util.save_entry(new_entry_name, content)
entry = util.get_entry(new_entry_name)
if entry is not None:
return HttpResponseRedirect(f"/wiki/{new_entry_name}/")
else:
return HttpResponse("Oop something went wrong there")
return render(request, "encyclopedia/entry.html", {
"error": "",
"title": entry_name,
"content": request.GET.get("content")
})
You can try to change your form action bcs i`ve never seen someone doing '=' while giving an id or slug in action
try this:
<form action="{% url 'edit' entry_title %}" method="get">
And btw can you add your models and views.py for better understanding
Related
This is the extention of the same problem i asked about in a previous question.
The problem i'm having here now is that after fixing the problem with the trans views function and expecting the program to run without problems, i get the following error
NoReverseMatch at /wiki/Python/edit
Reverse for 'edit' with keyword arguments '{'title': ''}' not found.
Which i can't for the life of me understand considering that i AM passing the title argument in the html and set up the edit views function and the urlpath in urls.py to expect the title argument.
when i take a closer look at the traceback, it highlights this block of code from the edit views function.
return render(request, "encyclopedia/edit.html", {
"form": EntryForm(initial={
"title": title,
"content": entry
})
})
but i don't understand what the problem is here?
this is the final part of the project i'm working on so i'll be very grateful for any and all help.
below is the relevant code.
HTML
entry.html
<!-- The edit button in the entry's page -->
<form action="{% url 'wiki:trans' %}" method="POST">
{% csrf_token %}
<input type=hidden value={{title}} name="title">
<input type=submit value="Edit">
</form>
edit.html
<!-- the edit page -->
{% block body %}
<h1>Edit Entry</h1>
<br>
<form action="{% url 'wiki:edit' title=title %}" method="POST">
{% csrf_token %}
{{form}}
<input type="submit" value="Save" id="save">
</form>
{% endblock %}
view.py
class EntryForm(forms.Form):
title = forms.CharField(label="Title")
content = forms.CharField(widget=forms.Textarea)
def trans(request):
title = request.POST.get("title")
return redirect("wiki:edit", title=title)
def edit(request, title):
if request.method == "GET":
entry = util.get_entry(title)
return render(request, "encyclopedia/edit.html", {
"form": EntryForm(initial={
"title": title,
"content": entry
})
})
else:
form = EntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return redirect("wiki:title", title=title)
urls.py
app_name = "wiki"
urlpatterns = [
path("", views.index, name="index"),
path("search", views.search, name="search"),
path("new", views.new, name="new"),
path("trans", views.trans, name="trans"),
path("<str:title>/edit", views.edit, name="edit"),
path("random", views.rand, name="random"),
path("<str:title>", views.title, name="title")
]
def edit(request, title):
if request.method == "GET":
entry = util.get_entry(title)
return render(request, "encyclopedia/edit.html", {
"form": EntryForm(initial={
"title": title,
"content": entry
})
})
That render() call is not passing a value for title, therefore the template tries to use a blank value, which is not allowed.
The title var that you are passing to title=title dict is empty that means that the title variable has no data. To fix it make sure that title has a value or change that as optional argument in the url patterns.
You can fix it doing the following:
def edit(request, title=None):
Then title will take a default value if you don't pass it.
I got an error message: "submission() takes exactly 2 arguments (1 given)" and I suspect that I didn't pass the 2 parameters successfully. I have struggled it for over 2 days now. Can anyone give me a quick diagnosis of what went wrong?
Here is my submission.html
<form method="post" action="{% url 'submission' %}" enctype="multipart/form-data">
{% csrf_token %}
<div>
<td>{{ form.title.label_tag }}</td>
<td>{{ form.title }}</td>
</div>
<div>
<td>{{ form.message.label_tag }}</td>
<td>{{ form.message }}</td>
</div>
<div>
<input type="text" name="image_id" />
<input type="hidden" name="next" value="{{ next }}" />
<input type="submit" value="Store Post" />
</div>
Register for an account<br>
Login<br>
Logout<br>
See All Comments<br>
Submit
</form>
Here is part of my view.py. the purpose is trying to upload image files.
def submission(request, image_id):
form = PostForm()
if request.user.is_authenticated() and request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid() == True:
post_to_submit = Post()
post_to_submit.post_title = form.cleaned_data['title']
post_to_submit.post_text = form.cleaned_data['message']
post_to_submit.pub_date = datetime.datetime.now()
post_to_submit.user = request.user
post_to_submit.save()
image = Image.objects.get(id=image_id)
image.comments.add(post_to_submit)
template = loader.get_template('discussion/index.html')
post_list = Post.objects.order_by('-pub_date')
context = {'post_list': post_list, 'image_id' : image_id}
else:
return HttpResponse(form.errors.__str__())
elif request.user.is_authenticated() and request.method != 'POST':
form = PostForm()
template = loader.get_template('discussion/submission.html')
context = {'form' : form, 'image_id' : image_id}
elif request.user.is_authenticated() == False:
template = loader.get_template('registration/login.html')
context = {}
return HttpResponse(template.render(context, request, {'image':image}))
I am not sure that will only get the issue that you have posted, because I see many bugs in your codes... The structure is not good. Explanations
Hopefully this will help you spot out where you've messed up in your codes.
1) User Authenticated / Request.GET: redirect to submission template with form and id as variables. In that templates, the form action needs a required argument image_id because it's shown clearly in def submission(request, image_id):.
By this link Submit, I actually realize that you did not set your urls to receive any arguments.
return HttpResponse(template.render(context, request, {'image':image})) will generate NameError: name 'image' is not defined
2) User Not Authenticated / Any Request: you render the template registration/login.html with no context variables.
In that case
this line return HttpResponse(template.render(context, request, {'image':image})) will generate NameError: name 'image' is not defined
3) User Authenticated / Request.POST: when the user submit the form.
you will not get any error if form is valid, because the image variable exists:
'''your codes'''
image = Image.objects.get(id=image_id)
image.comments.add(post_to_submit)
Possible ways to fix the issue posted
you can send the image_id through context and send it back via an hidden input inside the form rather than via form action url. No need to have argument in your view. def submission(request):
<input type="hidden" value="{{ image_id }}" name="image_id" />
In case you need the image_id inside the url, just set up your urls.py properly by adding the regex argument, and edit your form action url by adding the image_id argument
<form method="post" action="{% url 'submission' image_id %}" enctype="multipart/form-data">
Form is not shown in html correctly.I wrote in search.html,
{% load static %}
<form action='/search/' method='POST>
<table>
{{ form.as_table }}
</table>
<input name="submit" type="Search" />
{% csrf_token %}
</form>
in views.py
def search(request):
form = SearchForm()
if request.method == 'GET':
return render_to_response(
'search.html', {'form': form}, RequestContext(request))
elif request.method == 'POST':
form = SearchForm(request.POST)
search_result = POST.objects.all()
if form.is_valid():
result = search_result.filter(Q(title__contains=form.cleaned_data['keyword']))
return render_to_response('search.html',{'form':form, 'result':result})
When I access search method,search.html is shown as strings like
now search.html
It is not From,so I really cannot understand why such a thing happens.No error happens but UserWarning: A {% csrf_token %}was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.
"A {% csrf_token %} was used in a template, but the context " is shown in terminal.How should I fix this?What is wrong in my code?
This may not be the issue, but I think your input tag is wrong, it should be this:
<input name="submit" type="Search">
As here : https://www.w3schools.com/tags/tag_input.asp
I have a simple form in my template, index.html:
{% if stripped_thumbnail_file_list %}
{% for thumbnail_name in stripped_thumbnail_file_list %}
<div class="">
<div class="">
This is my form
<form class="" action="{% url 'index' %}" method="post">
{% csrf_token %}
<input type="image" value="{{ thumbnail_name }}" src="{{ MEDIA_URL}}thumbnails/{{ thumbnail_name }}.jpg">
</form>
</div>
</div>
{% endfor %}
{% else %}
<p>No videos are available.</p>
{% endif %}
I want the index view to pull the {{ thumbnail_name }} value from this form and use it as a variable when the index view redirects to a different view that will use that name to play a matching video.
I have been unsuccessful in trying to pull that value from the form as I have it. I suspect this may because I'm not creating a Django form object. I tried to create that object, but I can't find any examples of a Django form object as an image like I have in my form.
What should that look like? Or, can someone make a recommendation on how to pull the value from the form as is?
EDIT: adding views.py snippet:
def index(request):
# if this is a POST request we need to process the form data
if request.POST:
# get thumbnail_name from form
# redirect to a new URL (hardcode thumbnail name for now):
return HttpResponseRedirect('2017-02-01_04-29-10/video/')
thumbnail_file_list = get_file_list(target_directory, ".jpg")
stripped_thumbnail_file_list = strip_file_extension(thumbnail_file_list)
template = loader.get_template('dash/index.html')
context = {
'stripped_thumbnail_file_list': stripped_thumbnail_file_list,
}
return HttpResponse(template.render(context, request))
def video(request, file_name):
print("this is the file name passed: " + file_name)
template = loader.get_template('dash/video.html')
context = {
'file_name': file_name,
}
return HttpResponse(template.render(context, request))
First: you need to declare the 'name' attribute on your form imput.
<input name="thumbnail_name" type="image" value="{{ thumbnail_name }}" src="{{ MEDIA_URL}}thumbnails/{{ thumbnail_name }}.jpg">
Second: Why don't you just set the 'action' of the form to your 'video' function (when you perform a redirect, you are losing all your POST data).Then, from there you could retrieve the value: something like that
def video(request):
file_name = request.POST.get('thumbnail_name')
print("this is the file name passed: " + file_name)
template = loader.get_template('dash/video.html')
context = {
'file_name': file_name,
}
return HttpResponse(template.render(context, request))
Hope it helps
I'm getting this error when submit:
CSRF verification failed. Request aborted.
I've got this far following the documentation, but I don't fully understand it and it's definitely wrong. I just want to take a query word from my search box(form) and pass it to a python script as an argument. I'm new to Django and getting stuck on the easiest things.
In models.py:
class QueryForm(forms.Form):
query = forms.CharField(label='query',max_length=100)
I added this line to my urls.py
url(r'^results/$', 'tweemo.views.results'),
On my homepage where my search box is I have this code for my form:
<form action="/home/results/" method="post">
<label for="query">Search:</label>
<input id="query" type="text" name="query" value="{{ current_query }}">
<input type="submit" value="ok">
</form>
In views.py I added these two functions:
def get_query(request):
if request.method == 'POST':
form = QueryForm(request.POST)
if form.isvalid():
return HttpResponseRedirect('/thanks/')
else:
form = QueryForm()
return render(request, 'results.html', {'form': form})
def results(request):
return render_to_response('results.html',{'here':TwitterStream.objects.all() })
MY results.html contains just this:
<form action="/home/results/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit"/>
</form>
You must just add the {% csrf_token %} tag inside EVERY <form></form> tag which has method to be post in your template.
So the below markup should be corrected:
<form action="/home/results/" method="post">
{% csrf_token %}
<label for="query">Search:</label>
<input id="query" type="text" name="query" value="{{ current_query }}">
<input type="submit" value="ok">
</form>
Well the problem is that you are not passing the csrf token to the form , you need to pass the csrf token to the render function in order for it to be applied in the form . To accomplish this you need to associate the csrf token to the request.
def get_query(request):
if request.method == 'POST':
form = QueryForm(request.POST)
if form.isvalid():
return HttpResponseRedirect('/thanks/')
else:
form = QueryForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('results.html', args)
def results(request):
return render_to_response('results.html',{'here':TwitterStream.objects.all() })