CS50w - Project 1 - 404 page shown instead of search page - django

I try to solve cs50w project 1. But I faced an error in the project.
This is the layout.html file. I have a form action: go to search, and the name is q
enter image description here
<form action="{% url 'search' %}" method="POST">
{% csrf_token %}
<input class="search" type="text" name="q" placeholder="Search Encyclopedia">
</form>
urls.py
urlpatterns = [
path("", views.index, name="index"),
path("<str:title>/", views.title, name="title"),
path("search/", views.search, name="search"),
]
views.py
def search(request):
if request.method == "POST":
entry_search = request.POST['q']
html_content = markdown2.markdown(util.get_entry(entry_search))
if html_content is not None:
return render(request, "encyclopedia/title.html", {
"content": html_content,
"title": entry_search,
})
When I start my project and type something in the search bar, it sends me to the error.html page.
enter image description here
But it needs to take me to the title.html page.
Can you help me with this problem?
I need to face with title.html page, but it redirects to error.html

Related

How to make edit function work in views.py Django

I am creating an edit option for my entry. But instead of redirecting to the entry page, it is taking me to the addpage to create a new form. How do I redirect to the edit page?
Also, how do I make sure that the users previous input would reflect when they click on the edit button. I used initials - is this the best way to do it since I'm not using models but rather forms.Form.
VIEWS.PY
class AddPageForm(forms.Form):
title = forms.CharField(max_length=20)
content = forms.CharField(widget=forms.Textarea(
attrs={
"class": "form-control",
"placeholder": "Tell us more!"
})
def edit_page(request, title):
entry = util.get_entry(title)
if request.method == "POST":
form = AddPageForm(request.POST, initial={
"title": title,
"content": content
})
if form.is_valid():
util.save_entry(title, content)
return redirect('encyclopedia:entrypage', title=title)
else:
form = AddPageForm()
return render(request, "encyclopedia/editpage.html", {"form":form})
EDIT PAGE
{% block body %}
<h1>Edit {{ title }}</h1>
<form action="" method="post">
{% csrf_token %}
{% form %}
<input type="submit" value="Submit" class="btn btn-secondary">
</form>
ENTRY PAGE
{% block body %}
{{ content|safe }}
Update
<!-- <input="text" name="title" value="{{game.title}}" />
<input="text" name="genre" value="{{game.genre}}" /> -->
{% endblock %}
URLS.PY
app_name = "encyclopedia"
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:title>", views.entry_page, name="entrypage"),
path("search", views.search, name="search"),
path("add_page", views.add_page, name="addpage"),
path("edit_page/<str:title>", views.edit_page, name="editpage")
]
I think the issue with your code is that it is calling a redirect on a url that doesn't exist. 'encyclopedia:entrypage' does not exist in your urls.py. There are two ways of fixing this. Option #1 Create a url for entry page in urls.py with name=entrypage and a parameter in the url denoting which entrypage. Or option #2 Return directly to the entrypage view in the edit_page function. Here's a rough sketch of how you would do that
In edit_page in views.py:
# ...Code above
if form.is_valid():
util.save_entry(title, content)
return entry_page_view(request, title)
# 'title' if this view has a title passed as a kwarg or arg
# Code below...

Log out when sending a form

I've created an app where you can make comment (which sends a form to a database and saves it) if you're login on only, but when I press the button "Create" instead of redirecting me to the page where it show all the comments, it logs me out and bring me back to the "log out" view (which is / )
the create Template:
{% extends 'base.html' %}
{% block content %}
<div class="create_comment">
<h2>Write a comment</h2>
<form class="site-form" action="{% url 'create' %}" method="post">
{% csrf_token %}
{{form}}
<input type="submit" value="Create">
</form>
</div>
{% endblock %}
The Views of Create:
#login_required(login_url='/userprofile/login/')
def comments_create(request):
if request.method == 'POST':
form = forms.CreateComment(request.POST)
if form.is_valid():
form.save()
return redirect('/usercomments')
else:
form = forms.CreateComment()
return render(request,'usercomments/comments_create.html', {'form':form})
Log out view:
def logout_view(request):
if request.method == 'POST':
logout(request)
return redirect('/')
else:
pass
usercomments Urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$',views.comments_list, name="list"),
url(r'^create/$', views.comments_create, name="create"),
url(r'^(?P<slug>[\w-]+)/$',views.comments_detail, name="detail"),
]
userprofile urls.py:
from django.conf.urls import url
from . import views
app_name = 'userprofile'
urlpatterns = [
url(r'^signup/$', views.signup_view, name="signup"),
url(r'^login/$', views.login_view, name="login"),
url(r'^logout/$',views.logout_view, name="logout"),
]

Need help to solve newsletter form issues in base template

Here is what i have in base.html (inside the footer, so this newsletter form will be in every page)
<form action="" method="POST">
{% csrf_token %}
<div class="form-group">
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder='Enter email address' onfocus="this.placeholder = ''" onblur="this.placeholder = 'Enter email address'">
<div class="input-group-append">
<button class="btn" type="submit"><span class="lnr lnr-arrow-right"></span></button>
</div>
</div>
</div>
</form>
Here is the model (subscribe/models.py)
class Subscriber(models.Model):
email = models.EmailField()
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.email
what i have in views.py
def subscribe_form(request):
if request.method == 'POST':
email = request.POST.get('email')
new_email = Subscriber()
new_email.email = email
new_email.save()
return redirect('home-page')
here is urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.PostListView.as_view(), name='home-page'),
path('subscribe/', views.subscribe_form, name='subscriber'),
path('archive/', views.archive, name='archive-page'),
path('category/', views.category, name='category-page'),
path('contact/', views.contact, name='contact-page')
]
after submitting the submit button i'm getting this error in shell
Method Not Allowed (POST): /
Method Not Allowed: /
[18/Jan/2020 04:13:11] "POST / HTTP/1.1" 405 0
so, i'm a beginner, im trying to build a blog, but i didn't find any useful solution that can solve this issue. maybe i'm going totally wrong, but anyway if someone can help me to make this working.
Thank you all.
In your index URL, you are not allowed to post.So change it to subscribe/
<form action="{% url 'subscriber' %}" method="POST>

Django NoReverseMatch when trying to logout

I have a django view function signout that I want to call form a form/template. When i click logout, it calls the function but the redirect after doesnt work. I get the message Reverse for '<WSGIRequest: POST '/account/signout'>' not found. '<WSGIRequest: POST '/account/signout'>' is not a valid view function or pattern name.
Urls.py
urlpatterns = [
path('register', views.register, name='register'),
path('login', views.login, name='login'),
path('signout', views.signout, name='signout'),
path('dashboard', views.dashboard, name='dashboard'),
]
Views.py
def signout(request):
if(request.method == 'POST'):
auth.logout(request)
messages.success(request, 'You are logged out!')
return redirect(request, 'index')
Template form
<form action="{% url 'signout'%}" id="logout" method="POST">
{% csrf_token %}
<input type="hidden">
<button type="submit" class="btn btn-primary btn-sm"><i class="fas fa-sign-out-alt"></i>
Log Out</button>
</form>
What is going wrong?? The rest of routes work just fine and they are declared the same as signout.
You are doing wrong in your view .You don't need parenthesis while checking the if condition and redirect doesn't take the request parameter.
Change your view like this
def signout(request):
if request.method == 'POST':
auth.logout(request)
messages.success(request, 'You are logged out!')
return redirect('index')

Add ?q=search+term in django url

I want to integrate elastic search with django but first I need to get a nice parameter in url
http://127.0.0.1:8000/search?q=search+term
urls.py (of the view)
urlpatterns = [
path('?q=', SearchIndexView.as_view(), name="search-index"),
]
urls.py (of the app)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('home.urls')),
path('u/', include('user.urls')),
path('search', include('search.urls')),
]
That is what I have so far but I cant figure out how to make it work.
I want to use tha path() and not url() if possible
HTML FORM
<form action="{%url 'search' %}" method="get">
<input type="text" name="q" placeholder="Search...">
<button type="submit"></button>
</form>
urls
path('search/',views.search,name='search')
views
def search(request):
query = request.GET.get('q')
if query:
print("do your stuff here")
You don't need to define url query strings in urls.py. You can keep the url like this:
path('', SearchIndexView.as_view(), name="search-index"),
and in SearchIndexView you can do it like this:
q = request.GET.get('q')
keep your url like this
urlpatterns = [
path('', SearchIndexView.as_view(), name="search-index"),
]
in the html form
<form method='GET'>
and in the input put name="q"
in Django generic views you can create search views as follows for model Blog
class SearchResultView(ClientMixin, TemplateView):
template_name = 'clienttemplates/clientsearchresult.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
query = self.request.GET.get('q')
if query:
lookup = Q(title__icontains=query)
search_list = Blog.objects.filter(lookup)
context["slist"] = searchlist
return context
in html simply put name='q' inside input tag
<input type="text" class="search-field " placeholder="Search Blog..." value="" name='q'>
in urls.py
path('search/result', SearchResultView.as_view(), name="searchresult"),
in clientsearchresult.html you can simply add
{% if slist %}
{% for blog in slist %}
{{blog.title|title}}
{{bog.content|safe}}
{% endfor %}... and so on
{% endif %}