I'm using the wagtail cms to do a search. I'm using the default search in the /search folder. When I preform a search I get the following exception thrown at me.
AttributeError at /search/
module 'search.views' has no attribute 'search'
This is my views.py
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.shortcuts import render
from wagtail.core.models import Page
from wagtail.search.models import Query
def search(request):
search_query = request.GET.get('query', None)
page = request.GET.get('page', 1)
# Search
if search_query:
search_results = Page.objects.live().search(search_query)
query = Query.get(search_query)
# Record hit
query.add_hit()
else:
search_results = Page.objects.none()
# Pagination
paginator = Paginator(search_results, 10)
try:
search_results = paginator.page(page)
except PageNotAnInteger:
search_results = paginator.page(1)
except EmptyPage:
search_results = paginator.page(paginator.num_pages)
return render(request, 'search/search.html', {
'search_query': search_query,
'search_results': search_results,
})
This is my template/search/search.html
{% extends "base.html" %}
{% load static wagtailcore_tags %}
{% block body_class %}template-searchresults{% endblock %}
{% block title %}Search{% endblock %}
{% block content %}
<h1>Search</h1>
<form action="{% url 'search' %}" method="get">
<input type="text" name="query"{% if search_query %} value="{{ search_query }}"{% endif %}>
<input type="submit" value="Search" class="button">
</form>
{% if search_results %}
<ul>
{% for result in search_results %}
<li>
<h4>{{ result }}</h4>
{% if result.search_description %}
{{ result.search_description }}
{% endif %}
</li>
{% endfor %}
</ul>
{% if search_results.has_previous %}
Previous
{% endif %}
{% if search_results.has_next %}
Next
{% endif %}
{% elif search_query %}
No results found
{% endif %}
{% endblock %
}
I'm getting the following error when I preform a search
AttributeError at /search/
module 'search.views' has no attribute 'search'
URLS.py
from search import views as search_views
urlpatterns = [
url(r'^django-admin/', admin.site.urls),
url(r'^admin/', include(wagtailadmin_urls)),
url(r'^documents/', include(wagtaildocs_urls)),
url(r'^search/$', search_views.search, name='search'),
url(r'sitemap.xml', sitemap),
url(r'^wagtail-transfer/', include(wagtailtransfer_urls)),
]
Directory Structure
I don't see any error. What I'm assuming you have a django package by the same name 'search' installed. So I think changing your app name would resolve your problem.
On the other hand you can separate app urls from main urls and use relative import.
To do that you have to do
create a file named urls.py in your search app.
from django.urls import path
from . import views as search_view
urlpatterns = [
path('', search_views.search, name='search')
]
include urls.py(form search) in your main urls.py
#from search import views as search_views
urlpatterns = [
url(r'^django-admin/', admin.site.urls),
url(r'^admin/', include(wagtailadmin_urls)),
url(r'^documents/', include(wagtaildocs_urls)),
url(r'^search/', include('search.urls')),
url(r'sitemap.xml', sitemap),
url(r'^wagtail-transfer/', include(wagtailtransfer_urls)),
]
Related
I have a view in views.py:
def simple_upload(request):
if request.method == 'POST' and request.FILES['myfile']:
myfile = request.FILES['myfile']
fs = FileSystemStorage()
filename = fs.save(myfile.name, myfile)
uploaded_file_url = fs.url(filename)
print(uploaded_file_url)
context = {
'uploaded_file_url': uploaded_file_url
}
return render(request, 'simple_upload.html', context)
return render(request, 'simple_upload.html')
Then, a url in urls.py:
urlpatterns = [
path('', views.project_index, name='project_index'),
path('<int:pk>/', views.project_detail, name='project_detail'),
path('upload/', views.simple_upload, name='upload')
]
And when I hit the route /projects/upload, instead of a form I get an empty page. However, the simple_upload.html route has this structure:
{% extends "base.html" %}
<h1>H</h1>
{% load static %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile">
<button type="submit">Upload</button>
</form>
{% if uploaded_file_url %}
<p>File uploaded at: {{ uploaded_file_url }}</p>
{% endif %}
<p>Return to home</p>
{% endblock %}
You can see, I'm getting a blank page.
No errors are occurred.
I figured out the problem. You have to write {% block page_content %} in the template instead of {% block content %}, because in the base.html I have this line:
{% block page_content %}{% endblock %}
I am coding a basic login and register page app in Django/Python
Currently, after someone logs in, it redirects them back to the register page. I am trying to change the redirect path to "home/"
Please see the following code:
URLS.PY:
from django.contrib import admin
from django.urls import path , include
from accounts import views as v
from main import views as views
urlpatterns = [
path('admin/', admin.site.urls),
path('home/' , views.home , name = 'home'),
path('', v.register , name='register'),
path('' , include('django.contrib.auth.urls') , name = 'login'),
]
Views.py:
from django.shortcuts import render , redirect
from .forms import RegisterForm
# Create your views here.
def register(response):
if response.method == "POST":
form = UserCreationForm(response.POST)
if form.is_valid():
form.save()
return redirect("/home")
else:
form = RegisterForm()
return render(response, "registration/register.html", {"form":form})
Login.html
{% extends "main/base.html"%}
{% block title %}
Login here
{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<form class="form-group" method="post">
{% csrf_token %}
{{ form|crispy }}
<p>Don't have an account ? Create one </p>
<button type="submit" class="btn btn-success">Login</button>
</form>
{% endblock %}
Register.html
{% extends "main/base.html"%}
{% block title %}Create an Account{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<form method="POST" class="form-group">
{% csrf_token %}
{{ form|crispy }}
<p>Already have an account? Login here</p>
<button type="submit" class="btn btn-success">Register</button>
</form>
{% endblock %}
You can use this in settings.py file to redirect user after login :-
LOGIN_REDIRECT_URL = 'home/'
I don't know why I am getting a 404 error on the page flights/1 when clearly, I have a url pattern for
<int:flight_id> (flights is a app). Help!
My urls.py for the project
from django.contrib import admin
from django.urls import path
from django.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('flights/', include('flights.urls'))
]
My urls.py for the flights app
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("<int:flight_id>", views.flight, name="flight"),\
]
And the views.flight
def flight(request, flight_id):
flight = Flight.objects.get(id=flight_id)
return render(request, "flights/flight.html", {
"flight": flight,
"passengers": flight.passengers.all(),
"non_passengers": Passenger.objects.exclude(flights=flight).all()
})
Template
{% extends "flights/layout.html" %}
{% block body %}
<h1>Flight {{ flight.id }}</h1>
<ul>
<li>Origin: {{ flight.origin }}</li>
<li>Destination: {{ flight.destination }}</li>
<li>Duration: {{ flight.duration }}</li>
</ul>
<h2>Passengers</h2>
<ul>
{% for passenger in passengers %}
<li>{{ passenger }}</li>
{% empty %}
<li>No passengers.</li>
{% endfor%}
</ul>
<h2>Add Passenger</h2>
<form method="POST" action="{% url 'flight' flight.id book %}">
{% csrf_token %}
<select name="passengers">
{% for passenger in non_passengers %}
<option value="{{ passenger.id }}">{{ passenger }}</option>
{% endfor %}
</select>
</form>
Back to Flight List
{% endblock %}
With layout.html being html boilerplate code
I am getting the following error message http://prntscr.com/7f3l4d everytime I click on a link in template.html. Can someone help me out with this.
urls.py project
urlpatterns = [
url(r'^', include('feature.urls', namespace="feature")),
url(r'^admin/', include(admin.site.urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urls.py app
urlpatterns = [
url(r'^$', views.rock_and_feat, name='rock_and_feat'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
]
views.py
def rock_and_feat(request):
feats = Feat.objects.order_by('-created')[:3]
rocks = Rockinfo.objects.order_by('-rank')[:50]
context = RequestContext(request, {
'feats': feats, 'rocks': rocks})
return render_to_response('template.html', context)
class DetailView(generic.DetailView):
model = Feat
template_name = 'feature/detail.html'
context_object_name = 'feat'
template.html
{% extends "index.html" %}
{% block mainmast %}
<div id="wrapper">
{% if feats %}
{% for feat in feats %}
<div class="specialsticky">
<img src="{{ feat.image.url }}" alt="some text">
<h1 class="mast-header">
{{feat.title}}
</h1>
</div>
{% endfor %}
{% else %}
<p>No </p>
{% endif %}
</div>
{% endblock %}
When I click on the image in template.html the error occurs.Thanks.
You have placed the urls for your app in a namespace feature, so when referring to that url, you must use the namespace.
url(r'^', include('feature.urls', namespace="feature")),
Change your template to: <a href="{% url 'feature:detail' feat.id %}"> and it will work.
https://docs.djangoproject.com/en/1.8/topics/http/urls/#url-namespaces
I am making a simple blog app in Django as a learning exercise. I am able to add posts, see them all on the front page, so it is working so far. Where I am having an issue is creating a view that shows the whole post on a separate page. I want to click the title, and go to a page at the url /post/primary key that has the title and body. When I click on the link, I get a page with just the base.html. Not sure where I am missing anything, here are urls.py, views.py, and post.html:
urls.py
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('blog.views',
url(r'^$', 'frontpage'),
url(r'^post/(\d+)/$', 'post'),
)
urlpatterns += patterns('',
url(r'^admin/', include(admin.site.urls)),
)
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse
from django.shortcuts import get_object_or_404, render_to_response
from blog.models import *
views.py
def frontpage(request):
posts = Post.objects.all().order_by("-created")
paginator = Paginator(posts, 5)
page = request.GET.get('page', '1')
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = paginator.page(paginator.num_pages)
return render_to_response("list.html", dict(posts=posts, user=request.user))
def post(request, pk):
"""Single Post"""
post = Post.objects.get(pk = pk)
d = dict(post=post, user=request.user)
return render_to_response("post.html", d)
post.html
{% extends "base.html" %}
{% block content %}
<div class ="main">
<ul>
{% for post in posts.object_list %}
<div class = "title">{{ post.title }}</div>
<ul>
<div class="time"> {{ post.created }}</div>
<div class ="body"> {{ post.body|linebreaks }}</div>
</ul>
{% endfor %}
</ul>
</div>
{% endblock %}
Thanks in advance for your help.
I am assuming the page.html is actually the post.html you have in yoru codes sample???You no longer have a collection of posts but instead just have 1 post
This needs to change from: (which is looping through your posts)
{% extends "base.html" %}
{% block content %}
<div class ="main">
<ul>
{% for post in posts.object_list %}
<div class = "title">{{ post.title }}</div>
<ul>
<div class="time"> {{ post.created }}</div>
<div class ="body"> {{ post.body|linebreaks }}</div>
</ul>
{% endfor %}
</ul>
</div>
{% endblock %}
To something like (which just displays your single post):
{% extends "base.html" %}
{% block content %}
<div class ="main">
{{ post.title }}
{{ post.created }}
{{ post.body }}
</div>
{% endblock %}
You have to change urls.py to go to a page at the url /post/primary key.
urlpatterns = patterns('blog.views',
url(r'^$', 'frontpage'),
url(r'^post/(?P<pk>\d+)/$', 'post'),
)