Wagtail modeltranslation language switcher doesn't work on /search page - python

I have added search url to i18n_patterns, but the language switcher doesn't work on that page.
urls.py:
urlpatterns += i18n_patterns(
path("search/", search_views.search, name="search"),
path("", include(wagtail_urls)),
)
language switcher:
{% get_available_languages_wmt as languages %}
<div class="nav-item dropdown float-right">
<p class="nav-link dropdown-toggle m-auto" data-toggle="dropdown" role="button" aria-expanded="false">
{{ request.LANGUAGE_CODE|upper }}</p>
<div class="dropdown-menu w-25">
{% for language in languages %}
{% if language != request.LANGUAGE_CODE %}
<a class="dropdown-item" href="{% change_lang language page %}">{{ language|upper }}</a>
{% endif %}
{% endfor %}
</div>
</div>
Furthermore, when i add search url above root one the search page raises 404 page.
How can i make the language switcher work on the search page?

The language switcher uses the Wagtail page variable. See the change_lang template tag:
<a ... href="{% change_lang language page %}">...</a>
And search is a Django view, not a Wagtail page. The page variable is not defined.
You can make the switcher work on the search view by setting the href yourself:
{% for language in languages %}
<a href="/{{ language.code }}/search/"
{% endfor %}
Alternatively, you can create a Wagtail search page:
class SearchPage(Page):
def get_context(self, request):
context = super().get_context(request)
... # Copy the code from the current search view.
# Update and return the context
context.update({
'search_query': search_query,
'search_results': search_results,
})
return context
https://docs.wagtail.io/en/latest/topics/pages.html#customising-template-context
You also have to:
Rename (search_page.html) and rework (page.variable_name) your search template.
Remove the search url from urls.py
Add the SearchPage via the Wagtail admin interface to the page tree.

Related

How can I open a page with only one django model object's info after clicking it's ImageField on another page?

I am displaying django models on one of my website's pages. When I press one's ImageField on the page, I want it to open another page including only that one object. How do I do that ?
I thought about using the filter method in my views.py for filtering through my objects and finding that exact one, but I don't know what arguments to use.
Any ideas? (I am a beginner in django)
VIEWS.PY
from django.shortcuts import render
import requests
from . import models
def index(request):
return render(request, 'base.html')
def new_search(request): ********NOT IMPORTANT (I THINK)********
search = request.POST.get('search')
models.Search.objects.create(search=search)
objects = models.Object.objects.all()
results = objects.filter(name__contains=search).all()
args = { 'results': results }
return render(request, "my_app/new_search.html", args)
def individual_page(request):
link = request.GET.get('object-link')
objects = models.Object.objects.all()
return render(request, "my_app/individual_page.html")
MY TEMPLATE
{% extends "base.html" %}
{% block content %}
{% load static %}
<h2 style="text-align: center">{{ search | title }}</h2>
<div class="row">
{% for result in results %}
<div class="col s4">
<div class="card medium">
<div class="card-image">
<a name="object-link" href="{% url 'individual_page' %}"><img src="{{ result.image.url }}" alt=""></a>
</div>
<div class="card-content">
<p>{{result.name}}</p>
</div>
<div class="card-action">
View listing: Price TEST
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
So, the thing I want to do is: when I press the anchor tag that includes the image, I get redirectioned to another page which contains only that one object's info.

Django user authentication working properly EXCEPT 1 view/template

I am working with Django 1.11.5 and logging-in and validating users via Social Auth.
The user authentication, log-in and logoff are working as expected in 12/13 of my templates. All my templates extend my navbar and footer base.html template.
In 'base.html' I have the following code for the navbar:
{% if user.is_authenticated %}
<li class="nav-item">
<span class="nav-link" id="user-name">{{ request.user.username }}</span>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'logout' %}">Logoff</a>
</li>
{% else %}
<li class="nav-item log-in-link">
<a class="btn btn-primary nav-link log-in" href="{% url 'social:begin' 'google-oauth2' %}"><span>Log-In <i class="fa fa-google-plus" aria-hidden="true"></i></span></a>
</li>
{% endif %}
Now, this navbar code works properly in 12/13 of my templates. It is only for 1 template/view/URL where the user is not authenticated.
I have tried debugging by printing out the user name and information in the template giving me errors but it looks like the user is getting logged out when reaching that template via its URL and view.
I am totally lost.
Could someone point out things I can check/do to debug and locate the source of this logoff error? I can provide the relevant code if needed.
views.py code
def details_request(request, request_data_ID):
data_request_object = DatasetRequest.objects.get(pk=request_data_ID)
user_ID = data_request_object.user.username
has_attributes = False
request_data_attrs = []
if len(data_request_object.attr_names) > 0:
if len(data_request_object.attr_names['names']) > 0:
has_attributes = True
for idx, attr_names in enumerate(data_request_object.attr_names['names']):
request_data_attrs.append([attr_names,
data_request_object.attr_names['descriptions'][idx],
data_request_object.attr_names['types'][idx]])
data_request_detail_template = {
'dataset_request_title': data_request_object.dataset_title,
'dataset_request_description': data_request_object.dataset_description,
'dataset_votes': data_request_object.dataset_votes,
'dataset_date': data_request_object.created_date.strftime("%Y-%m-%d"),
'request_data_ID': request_data_ID,
'has_attributes': has_attributes,
'request_attrs': request_data_attrs,
'user': user_ID,
'is_completed': data_request_object.is_completed
}
data_comment_object = Comments.objects.filter(request_dataset_FK=data_request_object).order_by("-comment_votes")
if len(data_comment_object) > 0:
comment_list = []
for comment_object in data_comment_object:
if comment_object.isComment:
comment_list.append([comment_object.comment, comment_object.created_date.strftime("%Y-%m-%d"), comment_object.comment_votes, comment_object.pk, comment_object.user.username])
data_request_detail_template['comments'] = comment_list
return render(request, "detail_requests.html", data_request_detail_template)
You are specifying:
user_ID = data_request_object.user.username
and put it into context under user key.
In template you have {% if user.is_authenticated %} which means that you are trying to access missing attribute is_authenticated of user.username which always evaluates to False.

django get context from external app in main template

I have integrated djangocms blog in my project. In homepage sidebar i want to display latest blog posts. Problem is, my homepage is django-cms page and i can't get blog post objects. urls.py:
urlpatterns = i18n_patterns('',
url(r'^admin/', include(admin.site.urls)),
.....
url(r'djangocms_blog/', include('djangocms_blog.urls', namespace='djangocms_blog')),
url(r'^', include('cms.urls')),
)
Somehow here in main.html i should be able to get blog records:
{% extends "base.html" %}
<nav class="secondary-menu">
<ul class="nav">
<!-- i need display them here -->
</ul>
</nav>
Is there any elegant way to do this?
Use either an assignment_tag or an inclusion_tag:
Templatetag
# templatetags/blog_tags.py
from django import template
from djangocms_blog.models import Post
register = template.Library()
#register.assignment_tag()
def latest_posts_as(limit=5):
return Post.objects.order_by('-date_published')[0:limit]
#register.inclusion_tag('latest_posts.html', takes_context=True)
def latest_posts_inline(context, limit=5):
qs = Post.objects.order_by('-date_published')[0:limit]
context.update({'posts': qs})
return context
Snippet for inclusion tag
<!-- latest_posts.html -->
{% for post in posts %}
<p>{{ post }}</p>
{% endfor %}
Your home/whatever template
<!-- your_template.html -->
{% load blog_tags %}
<div>
<!-- using assignment_tag -->
{% latest_posts_as limit=20 as posts %}
{% for post in posts %}
<p>{{ post }}</p>
{% endfor %}
<!-- using inclusion_tag -->
{% latest_posts_inline limit=10 %}
</div>
The limit is optional - but could be handy :)
Came up with other solution. Created new django-cms plugin:
class BlogLatestEntriesPluginNav(BlogLatestEntriesPlugin):
name = _('Navigition latest blog entries')
render_template = 'latest_entries_nav.html'
plugin_pool.register_plugin(BlogLatestEntriesPluginNav)
where BlogLatestEntriesPlugin is plugin from djangocms_blog app. And created new template 'latest_entries_nav.html'. Then in main.html
<ul class="nav">
{% placeholder "left_sidebar" %}
</ul>
created placeholder and added that plugin.

Django Link to class based views url

I created with django a page where I can delete my blog articles using the class based views, I want to add link to each article but I'm struggling to do it.
here is the code to link to the class based view
views.py
user_delete_article = Article.objects.filter(user=request.user)
template.html
{% for article in user_delete_article %}
<p><a class="readmore" href="{% url "article.views.DeleteView" article.id %}">{{ article.titre }}</a></p>
{% endfor %}
urls.py
url(r'^delete/(?P<id>\d+)/$', DeleteView.as_view(), name="DeleteView"),
How can I make this work?
Assuming this is django 1.8
<a href="{% url "DeleteView" id=article.id %}">

URLs being produced correctly but not directing to correct template

I'm trying to follow the Simple Blog tutorial at Django By Example. I've managed to get as far as producing a site that loads correctly, but while the index view is loading find, and the links to the individual posts show up and appear to be formatted correctly, they point back to the index template so all that happens when you click on them is that it reloads the index view. I'm new to Django and the tutorial is sparse to say the least and not helped by the fact it's written for an old version of Django and I'm using 1.5. I've been staring at it all afternoon and I'm pretty lost.
Here's my urls.py
from django.conf.urls import patterns, url
from blog import views
urlpatterns = patterns('blog.views',
#index
(r"$", 'main'),
#ex: /1/
(r"^(\d+)/$", 'post'),
#ex: /add_comment/1/
(r"^add_comment/(\d+)/$", 'add_comment'),
)
my views.py
from blog.models import Post, PostAdmin, Comment, CommentAdmin
class CommentForm(ModelForm):
class Meta:
model = Comment
exclude = ["post"]
def main (request):
"""Main Listing."""
posts = Post.objects.all().order_by("-created")
paginator = Paginator(posts, 10)
try: page = int(request.GET.get("page", '1'))
except ValueError: page = 1
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = patinator.page(paginator.num_pages)
return render_to_response("blog/list.html", dict(posts=posts, user=request.user))
def post (request, pk):
"""single post with comments and comment form"""
post = Post.objects.get(pk=int(pk))
comments = Comment.objects.filter(post=post)
d = dict(post=post, comments=comments, form=CommentForm(), user=request.user)
d.update(csrf(request))
return render_to_response("blog/post.html", d)
and the list.html that contains the links that aren't going anywhere!
{% extends "blog/bbase.html" %}
{% block content %}
<div class="main">
<!-- Posts -->
<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>
<div class="commentlink">Comments</div>
</ul>
{% endfor %}
</ul>
<!-- Next/Prev page links -->
{% if posts.object_list and posts.paginator.num_pages > 1 %}
<div class="pagination" style="margin-top: 20px; margin-left: -20px; ">
<span class="step-links">
{% if posts.has_previous %}
newer entries <<
{% endif %}
<span class="current">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}
</span>
{% if posts.has_next %}
>> older entries
{% endif %}
</span>
</div>
{% endif %}
</div>
{% endblock %}
The Django URL resolver will return the first URL pattern that matches the incoming request. The regex for your 'main' view r"$" will match ANY incoming request since you are only looking for $ which is an end of string character.
You need to alter your 'main' URL regex to be r'^$'.
Alternatively, if you would like a catch-all view, you could move the 'main' view to the bottom of your URLs

Categories