Anchor Links from One Page to Another in Django - django

I have a real estate site that dynamically populates the /listings page with a list of all current listings in the database - and, I have a sidebar on the other pages that randomly displays one listing at a time if it is tagged as 'featured'. Since the sidebar is just a summary of the listing, I would like to provide a link that would take the visitor to the /listing list page and then based on the anchor, position the screen to the featured listing they would like to see. I can get the anchor to work if I hard code a link outside of the object loop for the listings, but can get it to work dynamically using the id of the listing.
Here is what I am attempting to do:
My Sidebar - Notice the 'More Info' link before the closing - I would like to use the unique object ID as the anchor link
{% for listing in listings %}
<div class="featured-block">
...
<p style="font-weight: bold">For more information please contact {{ user.first_name }} {{ user.last_name }} at {{ listing.phone }}.More Info</p>
</div>
{% endfor %}
I then have an <a name="{{ listing.id }}"></a> on the listing page; I even tried <div id="{{ listing.id }}"></div> with no luck.
Is it because the link from the sidebar is linking to an anchor on the listings page that hasn't been generated yet? Any help is always greatly appreciated. Thank you.

you can use
{% for listing in listings %}
<div class="featured-block">
...
<p style="font-weight: bold">For more information please contact {{ user.first_name }} {{ user.last_name }} at {{ listing.phone }}.{{listing.id}}</p>
</div>
{% endfor %}
The url template tag
{% url 'listing_list' listing.id %}
will generate the url for the id refer docs and
{{listing.id}}
will show the id on the html

Related

Django & HTMX - after GET show only section of html template

I want to create an instagram clone. I created a post.html which includes a post-card.html file for all posts and a post-filter.html to filter the posts.
<!-- simple post.html view -->
<div>
<div>
{% include '_includes/bars/post-filter.html' %}
</div>
<div id="more-posts-wrapper">
{% for post in posts %}
{% include '_includes/cards/post-card.html' %}
{% endfor %}
</div>
</div>
Now I added htmx to load more posts after clicking load more button. I tried to load the new posts after the existing one inside the div with id=more-posts-wrapper:
<div>
<div>
{% include '_includes/bars/post-filter.html' %}
</div>
<div hx-get="?page={{ page_obj.next_page_number }}"
hx-trigger="click"
hx-swap="innerHTML"
hx-target="#more-posts-wrapper">
<p>LOAD MORE</p>
</div>
<div id="more-posts-wrapper">
{% for post in posts %}
{% include '_includes/cards/post-card.html' %}
{% endfor %}
</div>
</div>
Unfortunately, if I press the button, the correct reponse post gets delivered but the whole post.html document gets loaded after the div with id=more-posts-wrapper. I only want to load the post-card.html file and not reload the post-filter.html file.
My views.py
class MemesView(ListView):
model = Post
template_name = 'memes.html'
context_object_name = 'posts'
paginate_by = 1
Does anyone know what I can do?
With HTMX we have two types of request:
Full page: when user loads the page we want to show the full template with the filters and the content as well.
Partial page: after the first load, we want to load only the content part via HTMX and update the corresponding part of the page.
We have to structure our templates accordingly, so we can reuse them in these two request.
The full page's template post_page.html:
<div>
<div>
{% include '_includes/bars/post-filter.html' %}
</div>
<div id="more-posts-wrapper">
{% include 'posts_partial.html' %}
</div>
</div>
And the posts_partial.html partial template where we put everything we want to load via HTMX:
<div hx-get="?page={{ page_obj.next_page_number }}"
hx-trigger="click"
hx-swap="innerHTML"
hx-push-url="true"
hx-target="#more-posts-wrapper">
<p>LOAD MORE</p>
</div>
<div id="more-posts-wrapper">
{% for post in posts %}
{% include '_includes/cards/post-card.html' %}
{% endfor %}
</div>
In this template we have the post cards for the selected page, furthermore we have to place our 'Load more' button here as well, because we have to update the page_obj.next_page_number value after each request at the button.
In the view function we can check for HX-Request: true header in order to detect a HTMX request. If the request was made by HTMX, we set the partial template in the get_template_names() method, otherwise we use the full page template.
class MemesView(ListView):
model = Post
context_object_name = 'posts'
paginate_by = 1
def get_template_names(self):
is_htmx = self.request.headers.get('HX-Request') == 'true'
return 'posts_partial.html' if is_htmx else 'post_page.html'
Furthermore I added the hx-push-url="true" so HTMX will update the page number in the URL, so the user can refresh and receive the correct page after a few HTMX request.

Django ListView works but DetailView not displaying Model Data

I am helping my daughter with her computing Project for school. It is a simple generic forum type application.
She has a ListView for a model which works fine:
{% extends 'users/main.html' %}
<!-- Here is where our content will begin -->
{% block content %}
<h1>This is posts.html!</h1>
<br/>
{% for obj in object_list %}
<h2>{{ obj.topic }}</h2>
{{ obj.date_posted }}
<br/>
{{ obj.content }}
<br/>
Author: {{ obj.author }}
<br/><br/>
{% endfor %}
{% endblock %}
She then added a DetailView which is simply the same code with the loop removed:
{% extends 'users/main.html' %}
<!-- Here is where our content will begin -->
{% block content %}
<h1>This is posts.html!</h1>
<br/>
{{ obj.id }}
<h2>{{ obj.topic }}</h2>
{{ obj.date_posted }}
<br/>
{{ obj.content }}
<br/>
Author: {{ obj.author }}
<br/><br/>
{% endblock %}
This is then called with a '....post/1/' (post id = 1 does exist (checked via DB Browser and in the ListView) and the path and naming of the template is correct.
Frustratingly, this displays the page but not the details inside the django temp language brackets (object.topic etc)!
When I look at the page source for the section dealing with the detail, I get:
screenshot of page
and the source code looks like so:
<h1>This is posts.html!</h1>
<br/>
<h2></h2>
<br/>
<br/>
Author:
<br/><br/
It is simply ignoring the bracketed templating code - any ideas?
Django DetailView returns 'object' inside context by default.
If you did not change 'context_object_name' variable, then use {{object}} instead of {{obj}}
<h1>This is posts.html!</h1>
<br/>
{{ object.id }}
<h2>{{ object.topic }}</h2>
{{ object.date_posted }}
<br/>
{{ object.content }}
<br/>
Author: {{ object.author }}
<br/><br/>
Really thanks a lot for all of this.
I corrected my template to include 'object' and made it march all conventions to avoid having to send in context information.
It still wouldn't work.
I rebooted localhost repeatedly because it all made no sense.
Finally, I rebooted my daughters PC and immediately, everything worked.
A lesson learned and as a dad helping a 17 year old daughter who did his Computer Science degree 40(!) years ago, another lesson in how complicated and challenging understanding a framework can be.
I must say - it has been fun.
Thanks again,
Howard.

Django - Validate search query within template

I need the search result to be validated together with the statement that it is a query inside the template.
So if the user is searching for another user and this user does not exist, it returns nothing. otherwise it returns the username of the user.
If request.user just checks the user that is logged in.
something like this
{% if request.GET.q and request.GET.q.is_authenticated %}
but this does not work :D Thank you
Can I use is_authenticated or is there a better way?
<li class="dropdown-hover">
<form class="form-inline">
{% include "tweets/search_form.html" %}
</form>
{% if user in request.GET.q.is_authenticated %}
<div class="dropdown-content x-card-4 x-bar-block" style="width:300px">
<a href='{{ request.GET.q }}'>{{ request.GET.q }}</a><br/>
{% else %}
<div class="dropdown-content x-card-4 x-bar-block" style="width:300px">
<a href='#'>No users found</a><br/>
{% endif %}
</li>
Thank you for any help
There is a better way, just do {% if request.user.is_authenticated %}.
you need to add loginRequiredMixin in your class so it allow to perform tasks only if user is logged in otherwise it redirect to login page.
#andre If you want to show/hide html tags in a template to the guest/logged-in user, you can use this {% if user.is_authenticated %} or you want to show some pages to the logged-in user #tabish-manzoor's solution is great.

Django 2.0 Notifications: How to overwrite the default list.html page for django-notifications

So, I recently imported Django-notifications and have successfully added a notification or two. Now I want to look at the list page. In my urls I have added the notification endpoint path('notifications/', include("notifications.urls")), and when I go to the url, I get the output that matches the documentation:
Now, How do I go about changing the notification url. I tried to create an app for notifications python manage.py startapp notifications, but it said that one already existed. I feel like I'm missing something simple, but I can't put a finger on it.
You can't create your own app, notifications, because you already have an installed app called notifications. This is the app you downloaded/installed and added to your_project/settings.py under INSTALLED_APPS
To view the default list, you can python manage.py runserver, and navigate to localhost:8000/notifications/' to see the defaultlist.html`.
From there, I recommend creating your own list. Looking at the documentation here, you'll find all the QuerySet methods. You can build a view based on these queries. e.g. your-app/views.py:
...
# Get all unread notifications for current user.
def unread_notifications(request):
context = {
'notifications': request.user.notifications.unread()
}
return render(request, 'your-app/unread_notifications.html', context)
And your your-app/unread_notifications.html (assuming bootstrap):
<ul class="notifications">
{% for notice in notifications %}
<div class="alert alert-block alert-{{ notice.level }}">
<a class="close pull-right" href="{% url 'notifications:mark_as_read' notice.slug %}">
<i class="icon-close"></i>
</a>
<h4>
<i class="icon-mail{% if notice.unread %}-alt{% endif %}"></i>
{{ notice.actor }}
{{ notice.verb }}
{% if notice.target %}
of {{ notice.target }}
{% endif %}
</h4>
<p>{{ notice.timesince }} ago</p>
<p>{{ notice.description|linebreaksbr }}</p>
<div class="notice-actions">
{% for action in notice.data.actions %}
<a class="btn" href="{{ action.href }}">{{ action.title }}</a>
{% endfor %}
</div>
</div>
{% endfor %}
</ul>

Django endless pagination url issue on page reload

I am using endless pagination for my django project. On a page where I display records as a report, things work well.
However, when I include some "operations" with my records, I have issues.
e.g. my table row displays information and has additional column which takes the user to edit form.
{% extends "base/home.html" %}
{% load endless %}
{% block maincontent %}
{% paginate 5 atlist %}
<table> class="table">
{% for rec in atlist %}
<tr>
<!-- ... Headers ... and other columns code taken out .... -->
<td>
<button class="btn btn-primary btn-sm" onclick="location.href='/secure/editmytypes?ID={{rec.uuid}}'">Edit</button>
<button class="btn btn-primary btn-sm" onclick="location.href='/secure/deletemytypes?ID={{rec.uuid}}'">Delete</button>
</td>
</tr>
{% endfor %}
</table>
{{ pages.previous }} {{ pages.next }}
{% endblock %}
When the above template is loaded the first time, {{ pages.previous }} {{ pages.next }} display proper links like
"/list?page=2"
and behaves properly if I only do next / previous page navigation.
But, when the user clicks on Edit link (Edit Button) in a row to goto the edit form - do the operation and come back to this list (both the forms save data and transfers control back to this list) the {{ pages.previous }} {{ pages.next }} links become
"/secure/editmytypes?ID='..uuid...'&pages=2"
or
"/secure/deletemytypes?ID='..uuid...'&pages=2"
Does anyone have any pointers I could use ?
Thanks in advance.
Changing the way my edit for returns control back to this list form did the trick for me.
I was doing
# return render(request,'base/list_mytypes.html',{'atlist':mytypeslist,},)
which was the problem .. I changed it to
return redirect('/secure/listmytypes',{'atlist':mytypeslist,},)
and now suddenly the page links are proper !!
Doing some R&D in this since I think both the shortcuts essentially achieve the same effect (I know they return different HttpResponse objects but that should not have any effect on a url in some other page - unless I am missing something here).