Can't use request 'get' in django - django

I am using django, and want to get simple 'get' request from server. It seems like view is taking it, and in console it have code '200'. But in view I try to check it someway, but I can't. Can somebody tell my what I am doing wrong.
This is my view:
def check_register(request):
if request.GET.get("sign_mail"):
return HttpResponse("YEAH, GET")
else:
return HttpResponse("no didn't")
My form:
<form action="/checkRegister/" method="GET">
<input class="header_input" type="text" size="25" name="sign_mail" placeholder="Email">
<button class="sign_btn" type="submit">ВОЙТИ</button>
</form>
My urls:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'$', views.index),
url(r'^checkRegister/$', views.check_register),
]

Related

Change how GET url is displayed

Summary: If I search 'apple', the url will be http://127.0.0.1:8000/search_results?csrfmiddlewaretoken=rlUwb5Ju3Xr585FarH5eAGQJtpog83hqW4wRysbsMWM6eiO3prcKRONY28N118gR&query=apple&button= and I just want to know if there is a way to change this to something cleaner like 127.0.0.1:8000/search_results/apple?
Here is my code:
urls.py
path('search_results', views.search_results, name = 'search_results'),
html:
<form action="{% url 'search_results' %}" method="GET">
{% csrf_token %}
<input name = 'query' type = 'text'/>
<button type="submit" name="button">Search</button>
</form>
and views.py:
def search_results(request):
query =request.GET.get('query')
return HttpResponse(query)
I had tried to change these 3 lines in their respective files:
`path('search_results/<str:query>')`, # thought this would achieve /search_results/apple url
<form action="{% url 'search_results' 'query' %}" method="GET">
def search_results(request, query):
but this did not work. Does anyone know how I can achieve this?
The GET parameters are encoded in the query string [wiki]. The query string is not part of the path. There is thus no way to encode this that way. But you can indeed make a "redirect view" that moves it to the path.
You can change the redirect to:
# app/views.py
from django.shortcuts import redirect
def search_redir(request):
query =request.GET.get('query')
return redirect('search_results', query=query)
def search_results(request, query):
# …
pass
In your urls.py, you then define two views: one that will "catch" the initial GET request with the querystring, and one where you move the query to the path:
# app/urls.py
from django.urls import path
urlpatterns = [
path('search_results/', views.search_redir, name='search_redir'),
path('search_results/<str:query>/', views.search_results, name='search_results'),
]
In your form however, you still use the redirect view. Note that since you perform a GET request you do not need to use the {% csrf_token %}:
<form action="{% url 'search_redir' %}" method="GET">
<input name="query" type ="text"/>
<button type="submit" name="button">Search</button>
</form>

How do you translate the slug value of a page?

I'm trying to implement a language switcher, for which I'm using the Django recommended form:
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
{% get_current_language as LANGUAGE_CODE %}
<input name="next" type="hidden" value="{{ redirect_to }}">
<input name="language" type="hidden" value="{% if LANGUAGE_CODE == 'en' %}es{% else %}en{% endif %}">
</form>
My urls.py is set up like so:
urlpatterns = [
# Wagtail urls
re_path(r'^cms/', include(wagtailadmin_urls)),
re_path(r'^documents/', include(wagtaildocs_urls)),
# Django urls
path('admin/', admin.site.urls),
path('i18n/', include('django.conf.urls.i18n')),
]
urlpatterns += i18n_patterns(
path(r'', include(wagtail_urls))
)
When I click to change my language, I am correctly forwarded to /en/slug or es/slug, depending on the language I have selected. However the actual slug value is not being translated. Since I have Spanish slugs for the Spanish pages, I am getting a 404 when I switch languages, because I am directed to the English slug value paired with the Spanish locale prefix (es).
I also tried using the slugurl_trans template tag, but that didn't seem to work (maybe because I'm not explicitly defining any URLs in my i18n_patterns call?).
Any guidance on this would be really helpful, as I've spent way too many hours on this!
It has been long but I'm going to post an answer anyway, the best way to get rid of the different slugs problem is by using django signals like this
#receiver(pre_save)
def set_translated_slug_on_new_instance(sender, instance, **kwargs):
if isinstance(instance, Page):
instance.slug_es = instance.slug_en

Django form POST with NoReverseMatch error

In html:
<form role="form" method="post" action="{% url 'myapp:add_review' %}" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<div class="col-sm-10">
<input id="review" name="review" type="text">
</div>
</div>
<button type="submit" class="btn btn-default"> Submit </button>
</form>
In views:
def add_reviews(request):
if request.method == "POST":
print "Post is here:", request.POST['review']
return render(request, 'myapp/single_item.html')
//or this?? return redirect('myapp:single_item')
In urls.py
app_name = 'myapp'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
# register, login, logout
url(r'^register/$', views.UserFormView.as_view(), name='register'),
url(r'^login/$', views.login_user, name='login'),
url(r'^logout/$', views.logout_user, name='logout'),
# individual article page
url(r'^(?P<item_id>[0-9]+)/$', views.single_item, name='single_item'),
url(r'^(?P<item_id>[0-9]+)/add_review/$', views.add_review, name='add_review'),
]
Really basic stuff, in each individual item page, I want a form to write and post reviews for each item, and go back to the same item page.
When I'm in the individual item page, gives me the following error:
Reverse for 'add_review' with arguments '('',)' and keyword arguments '{}' not found.
1 pattern(s) tried: ['(?P<item_id>[0-9]+)/add_review/$']
Generally, these types of errors indicate that something is not right with an URL, that such pattern was not found, that it misses some parameters and so forth. From this particular error it seems that you are not passing item_id to the url matcher. Hence, Django cannot find an appropriate URL. You have:
url(r'^(?P<item_id>[0-9]+)/add_review/$', views.add_review, name='add_review')
Notice that you wrote ?P<item_id>[0-9]+)/..., which means you must provide item_id whenever you want this URL to be resolved. Try adding item_id as a keyword argument:
<form role="form" method="post" action="{% url 'myapp:add_review' item_id= ... %}" enctype="multipart/form-data">
This should construct a valid url (e.g., .../1/add_review/), which should be recognised by Django. However, I believe your add_review() function will also need to take an item_id argument, otherwise you might get TypeError due to unexpected function arguments.
As for the return value, I would use redirect instead of render, as you are, well, redirecting after a successful POST. Though you might need to pass a item_id, too, since your URL config specifies that: a) URL should have item_id and b) single_item() expects item_id. Something like this should work:
def add_review(request, item_id):
...
return redirect('myapp:single_item', {'item_id': item_id})
And signature of single_item should be something like this: single_item(request, item_id).

Django Method Not Allowed (POST)

In views:
def article_add(request):
print request.user, " is adding an article"
if request.method == "POST":
web_url = request.POST['web_url']
Uploadarticle(web_url)
return redirect('myapp:index')
In html:
<form class="navbar-form navbar-right" role="form" method="post" action="{% url 'myapp:article_add' %}" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<div class="col-sm-10">
<input id="article_url" name="web_url" type="text">
</div>
</div>
<button type="submit" class="btn btn-default"> + </button>
</form>
In url.py:
app_name = 'myapp'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^$', views.article_add, name='article_add'),
]
What i'm trying to do here is to pass the url value through html to view, call the function to upload the database, redirect the user to the same home page as refresh then the newly added item will show up.
Somehow everytime I submit I got a blank page, in terminal I got an errors says:
Method Not Allowed (POST): /
"POST / HTTP/1.1" 405 0
As I can see in the code, you are using same URL for both view, so, whenever you hit URL /, the request goes to first view(IndexView) which probably does not have any post method. Change the URL for article_add view. Do like this:
app_name = 'myapp'
urlpatterns = [
url(r'^article-add/$', views.article_add, name='article_add'),
url(r'^$', views.IndexView.as_view(), name='index'),
]
You will be able to access view from URL {host_address}/article-add/
There is small mistake in your urls.py change your urls.py following way
app_name = 'myapp'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^article-add/$', views.article_add, name='article_add'),
]
if you are incuded the 'myapp' urls.py in the main project urls.py then in the form in html just put action="{% url 'article_add' %}" this way also.

Django: dynamic url via submit button

I want to use a dynamical url with Django for a search option in my database. I implemented an input text field for my search term and a submit button to start the query. So, when I click the button the new url of my search result should include the term from the text field (written by the user).
How can I implement a dynamic url using a submit button instead of a hyperlink? How do I get the value of my text field into my url? Can you please help me?
That is part of my (non-working) code:
urls.py
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^search/(?P<term>\w{2}_[0-9.]+)/$', views.search, name='search'),)
views.py
def search(request, term ):
search_term = request.GET['term']
#generate results for search_term
return render(request, 'app/results.html', {'list_of_r': list_of_r})
results.html
<form action="{% url 'app:search/{{term}}' %}" method="get">
{% csrf_token %}
<input id="text_id" type="text" name="term" maxlength="20" />
<input type="submit" value="submit" name="submit"/>
</form>
That is not how you do forms: but you don't need to. The GET request submitted by the form automatically includes the parameters in the form, that's the whole point: so if you submitted to the path /search, with the value "text_to_be_searched" in your term field, the URL woudl be "/search?term=text_to_be_searched". You don't need to do anything else.