django search returns a blank page - django

I have designed my search box in my django app but the search only returns the extended html page, not the search results.
#View
class SearchListProject(ListView):
paginate_by = 4
template_name = 'website/search_project.html'
def get_queryset(self):
search_project = self.request.GET.get('q')
return Project.objects.filter(description__icontains=search_project)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['search_project'] = self.request.GET.get('q')
return context
#url
path('search_project/', SearchListProject.as_view(), name='search_project'),
path('search_project/page/<int:page>', SearchListProject.as_view(), name='search_project')
#html
{% extends 'website/project_list.html' %}
<h3 class="alert alert-primary text-center">Search: {{ search_project }}</h3>
{% block previous_page_url %}
{% url 'website:search_project' page_obj.previous_page_number %}?q={{ search_project }}
{% endblock %}
{% block next_page_url %}
{% url 'website:search_project' page_obj.next_page_number%}?q={{ search_project }}
{% endblock %}
#my form
<form action="{% url 'website:search_project' %}">
<input type="text" name="q">
<button type="submit"><i class="icofont-search"></i></button>
</form>

Related

How to display search term on search results page in django?

I made a form and then i made little search form and it works but, i didnt display the search term on the search results page...
I just wanna show Search Results for (Search Term)
Here are my codes.
Views.py
class SearchResultsView(ListView):
model = Post
template_name = 'search.html'
def get_queryset(self):
query = self.request.GET.get('q')
object_list = Post.objects.filter(Q(soru1__icontains=query) | Q(soru2__icontains=query) |
Q(soru3__icontains=query) |
Q(soru4__icontains=query) |
)
return object_list
Base.html ( search bar in it)
<form class="d-flex" action="{% url 'search' %}" method="get">
<input class="form-control me-2" name="q" type="text" placeholder="Arama...">
<button class="btn btn-outline-success" type="submit">Ara</button></form>
And search.html
{% extends 'base.html' %}
{% block content %}
<h1>Search Results for </h1>
<ul>
{% for Post in object_list %}
<li>
{{ Post.soru1 }}
</li>
{% endfor %}
</ul>
{% endblock %}
You need to add query to context:
Views.py
class SearchResultsView(ListView):
model = Post
template_name = 'search.html'
def get_queryset(self):
query = self.request.GET.get('q')
object_list = Post.objects.filter(Q(soru1__icontains=query) | Q(soru2__icontains=query) |
Q(soru3__icontains=query) |
Q(soru4__icontains=query) )
return object_list
def get_context_data(self, **kwargs):
context = super(SearchResultsView, self).get_context_data(**kwargs)
context['query'] = self.request.GET.get('q')
return context
and in template:
{% extends 'base.html' %}
{% block content %}
<h1>Search Results for {{ query }} </h1>
<ul>
{% for Post in object_list %}
<li>
{{ Post.soru1 }}
</li>
{% endfor %}
</ul>
{% endblock %}

HTML layout object doesn't work

I quite new with Django Crispy Form and I have tried to add a HTML object in my form but it's not working. All the other elements are rendered but not the HTML.
This is my form:
forms.py
from crispy_forms.layout import Layout, Fieldset, HTML
class MyUserRegistrationForm(forms.ModelForm):
class Meta:
model = MyUser
fields = ['title', 'privacy_disclaimer_accepted']
def __init__(self, *args, **kwargs):
super(MyUserRegistrationForm, self).__init__(*args, **kwargs)
helper = FormHelper()
helper.form_method = 'post'
helper.form_class = 'form-horizontal'
helper.label_class = 'col-sm-2'
helper.field_class = 'col-sm-6'
helper.form_error_title = 'Form Errors'
helper.error_text_inline = True
helper.help_text_inline = True
helper.html5_required = True
helper.form_tag = False
helper.layout = Layout(
Fieldset('Information', 'title'),
Fieldset('Privacy Statement',
HTML("""
<div id="iframe" class="mt-5">
<h6>Notice/Disclaimer:</h6>
<div class="privacy-policy">
{% if privacy_disclaimer %}
{{ privacy_disclaimer }}
{% else %}
{% include "registration/privacy_policy.html" %}
{% endif %}
</div>
</div>
"""),
'privacy_disclaimer_accepted', )
)
I have a basic HTML file, where I have the normal html, header and body tags.
This is the HTML registration page:
register.html
{% extends "base.html" %}
{% block title %}Create an account{% endblock %}
{% block content %}
<div class="registration-page">
<h3 class="text-center">Create an account</h3>
<div class="registration-page__form">
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-error">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-error">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
<form action="" method="post">
{% csrf_token %}
{% load crispy_forms_tags %}
{{ form_myuser|crispy }}
<br/>
<div class="text-right">
<input type="submit" class="btn btn-primary btn--action" value="Create the account">
</div>
</form>
</div>
</div>
{% endblock %}
EDIT:
views.py
class RegisterView(View):
template_name = 'registration/register.html'
def _get_context_data(self, **kwargs):
context = {}
privacy_disclaimer = ''
context['privacy_disclaimer'] = privacy_disclaimer
if kwargs:
context.update(kwargs)
return context
def get(self, request, *args, **kwargs):
extra_context = {
'form_myuser': MyUserRegistrationForm(),
}
context = self._get_context_data(**extra_context)
return render(request, self.template_name, context)
I fixed the issue and the problem was the form loading.
I was loading it in the wrong way.
Instead of this {{ form_myuser|crispy }} I have to use this code {% crispy form_tolauser %}.

How to GET data by search word Django

I have problem getting the data to the home page.
I would like to filter out all the books based on Genre. I'm following the
MDN site for this.
index.html
{% extends "base_generic.html" %}
{% block content %}
<h1>Local Library Home</h1>
<p>Welcome to <em>Local Library</em>, a very basic Django website.</p>
<h2>Dynamic content</h2>
<form action="" method="get">
<input type="text" name="genre" placeholder="Search">
<input type="submit" value="Search">
</form>
{% endblock %}
urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^books/$', views.BookListView.as_view(), name='books'),
url(r'^(?P<string>[-\w]+)$', views.GenreListView.as_view(), name='index'),
]
GenreListView class
class GenreListView(generic.ListView):
model = Book
def get(request, string):
try:
book = Book.objects.all().filter(genre=string)
except Book.DoesNotExist:
raise Http404("Book does not exist")
return render(
request,
'index.html',
context={'book': book,}
)
I can't figure out what I'm missing or what else I have to do to get all the date based on genre?
EDIT:
whole index.html
{% extends "base_generic.html" %}
{% block content %}
<h1> Book List </h1>
<form action="" method="get">
<input type="text" name="genre" placeholder="Search">
<input type="submit" value="Search">
</form>
{% if book_list %}
<ul>
{% for book in book_list %}
<li>
{{ book.title }} ({{ book.author }})
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no books in the library</p>
{% endif %}
{% endblock %}
You should override get_queryset, No need to rewrite get
class GenreListView(generic.ListView):
model = Book
template_name = 'index.html'
def get_queryset(self):
books = Book.objects.all()
query = self.request.GET.get('genre', None)
if query:
return books.filter(genre=query)
return books
The exception Book.DoesNotExist will never
occur if you filter() queryset. it will always return a empty queryset in case of no object found

Rewrite form with django forms

I want to rewrite the vote form of the django tutorial polls application. But I can't figure out how to make a radio list for all choices of a question:
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
After a lot of experimenting this was the solution:
#forms.py
class VoteForm(forms.ModelForm):
choice = forms.ModelChoiceField(queryset=None, widget=forms.RadioSelect)
class Meta:
model = Question
exclude = ('question_text', 'pub_date')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['choice'].error_messages = {
'required': 'No choice selected.',
'invalid_choice': 'Invalid choice selected.'
}
instance = getattr(self, 'instance', None)
if instance:
self.fields['choice'].queryset = instance.choice_set
#vote.html
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/css/style.css' %}" />
<h2>{{ question.question_text }}</h2>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% if voted %}
<p><strong>Already voted on this question.</strong><p>
{% else %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.choice.errors }}
{{ form.choice }}
</div>
<input type="submit" value="Vote" />
</form>
{% endif %}
<p>View results?</p>
#views.py
class VoteView(generic.UpdateView):
template_name = 'polls/vote.html'
model = Question
form_class = VoteForm
def get_queryset(self):
return Question.objects.filter(pub_date__lte=timezone.now()).exclude(choice__isnull=True)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Check duplicate vote cookie
cookie = self.request.COOKIES.get(cookie_name)
if has_voted(cookie, self.object.id):
context['voted'] = True
return context
def get_success_url(self):
return reverse('polls:results', args=(self.object.id,))
def form_valid(self, form):
choice = form.cleaned_data['choice']
choice.votes = F('votes') + 1
choice.save()
redirect = super().form_valid(form)
# Set duplicate vote cookie.
cookie = self.request.COOKIES.get(cookie_name)
half_year = timedelta(weeks=26)
expires = datetime.utcnow() + half_year
if cookie and re.match(cookie_pattern, cookie):
redirect.set_cookie(cookie_name, "{}-{}".format(cookie, self.object.id), expires=expires)
else:
redirect.set_cookie(cookie_name, self.object.id, expires=expires)
return redirect

haystack on existing template

How to implement working SearchView in existing views.py?
I already have CBV, and added in urls.py as /moderate and want to apply search form in it. but always got "Results No results found."
This is my /moderate page with 3 forms, using SearchView and piece of code from tutorial in template.
And this from /search page, with urls(r'^search/$', include('haystack.urls'))
urls.py
urlpatterns= [
url(r'^search/', include('haystack.urls')),
url(r'^moderate/', Moderate.as_view(), name='moderate'),
]
views.py
class Moderate(SearchView):
#method_decorator(staff_member_required)
def dispatch(self, *args, **kwargs):
return super(Moderate, self).dispatch(*args, **kwargs)
#model = Ad
template_name = 'adapp/ad_moderate.html'
#template_name = 'search/search.html'
paginator_class = DiggPaginator
paginate_by = 10
ad_type = None
ad_sub_type = None
def get_queryset(self):
qs = super(Moderate, self).get_queryset().filter(ad_type__isnull=False,
ad_sub_type__isnull=False)
return qs
def get_context_data(self, **kwargs):
context = super(Moderate, self).get_context_data(**kwargs)
context['filter'] = ModerateFilter(self.request.GET)
return context
# define method to recieve fields from form, and change data accordings
def post(self, request, *args, **kwargs):
selected = request.POST['selected']
record = Ad.objects.get(pk=int(selected))
form = ModerateForm(request.POST, instance=record)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect('')
template/ad_moderate.html
{% extends 'base.html' %}
{% load i18n url_tags %}
{% block content %}
<div id="casing">
<div id="content">
{# filter form, to show only models with moderated=True #}
<form action="" method="get">
{{ filter.form.as_p }}
<input type="submit">
</form>
<h2>Search</h2>
{# search form right from tutorial #}
<form method="get" action="">
<table>
{{ form.as_table }}
<tr>
<td> </td>
<td>
<input type="submit" value="Search">
</td>
</tr>
</table>
{% if query %}
<h3>Results</h3>
{% for result in page.object_list %}
<p>
{{ result.object.title }}
</p>
{% empty %}
<p>No results found.</p>
{% endfor %}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
</form>
{% for object in filter %}
{# a lot of template tags and third form to change value of model #}
<form action="" method="POST">
{% csrf_token %}
<input type="radio" name="moderated" value="True">Accept
<br>
<input type="radio" name="moderated" value="False">Decline
<input type="hidden" value="{{ object.id }}"
name="selected">
<input class="btn" type="submit" value="moderate">
</form>
search_indexes.py
from .models import Ad
class AdIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
# my model, with one search should be
return Ad
templates/search/indexes/app/ad_text.txt
{{ object.title }}
{{ object.short_desc }}
{{ object.description }}
{{ object.experience }}
{{ object.skills }}
{{ object.name }}
{{ object.city }}
get_context_data():
context['search'] = SearchForm(self.request.GET).search()
Would solve a problem.
That means, I should create form and send return from .save() method, rather that django-like form instance.