pass title of page into url - python

Using Django I am trying to pass the title of the current page into a dynamic URL but I keep getting errors, the title of the page is also produced dynamically from other views.py functions.
Error
exception type: TypeError
exception value: edit_page() got an unexpected keyword argument 'title'
urls.py
path("wiki/edit/<str:title>", views.edit_page, name="edit")
HTML file
{% block title %} {{ title }} {% endblock %}
{% block body %}
<a class="page-link" href="{% url 'wiki:edit' page=title %}">edit page</a>
{% endblock %}
views.py
def edit_page(request, page):
page_request = page
if request.method == "GET":
return render(request, "encyclopedia/edit_page.html", {
"form": form,
"page": page_request
})

Update your parameter of edit_page(...) function to
def edit_page(request, title):
page_request = title
# rest of your code

Related

Return html tag by calling python function in django template

Guys actually i am expecting the django view should return only the tag like
def load_tags():
return httpresponse("<span>span tag</span>")
def home(request):
return render(request, 'index.html',{"func":load_tags()})
html file
<h2>Calling python function {{ func }} </h2>
-In browser it displayed as
Calling python function <HttpResponse status_code=200, "text/html; charset=utf-8">
-But i am expecting as
Calling python function span tag
Guys can you help me to achieve this functionality
I tried to solve your requirement like this...
views.py
def TagsView():
html_h1 = "<h1>Hello django</h1>"
html_italic = "<h4><i>Hello django</i></h4>"
html_hr = "<hr>"
my_code = "<code>print('Hello world')</code>"
return html_h1,html_italic,html_hr,my_code
def DemoView(request):
context = {"func":TagsView()}
return render(request, 'index.html',context)
HTML Code
{% block body %}
{% autoescape off %}
{% for i in func %}
{{i}}
{% endfor %}
{% endautoescape %}
{% endblock body %}
Output

Djange NoReverseMatch error - reverse for 'edit' with no arguments not found

In a Django app I am building for a course, I am attempting to pass a parameter from one template to a function in views.py through a url path.
The path definition in urls.py contains the parameter name, and the same name is required by the function in views.py.
The link in my template points to the correct url path and names a value for the parameter, but I am still receiving a NoReverseMatch error. Weird because I have another url path that requires a parameter and which is working perfectly.
entry.html Here is the link to the path called edit in urls.py. I want to pass the value of the variable entryTitle to the url as entry:
{% extends "encyclopedia/layout.html" %}
{% block title %}
{{ entryTitle }}
{% endblock %}
{% block body %}
{{ entry|safe }}
<button>
Edit Entry
</button>
{% endblock %}
urls.py the edit path is the last one defined in urlpatterns
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:entry>", views.entry, name="entry"),
path("search", views.search, name="search"),
path("new", views.new_page, name="new"),
path("wiki/edit/<str:entry>", views.edit, name="edit")
]
views.py This is the edit function, requiring entry as an argument UPDATE: also showing the entry function
class EditPageForm(forms.Form):
content = forms.CharField(
widget=forms.Textarea(),
label="Edit Content:")
def edit(request, entry):
if request.method == "POST":
#Edit file and redirect
form = EditPageForm(request.POST)
if form.is_valid():
content = form.cleaned_data["content"]
util.save_entry(entry, content)
return HttpResponseRedirect(reverse('entry', kwargs={'entry': entry}))
else:
#Load form with initial values filled
content = util.get_entry(entry)
form = EditPageForm(initial={"content": content})
return render(request, "encyclopedia/edit.html", {
"editform": form,
"entryTitle": entry
})
def entry(request, entry):
markdowner = Markdown()
entryPage = util.get_entry(entry)
if entryPage is None:
return render(request, "encyclopedia/notfound.html", {
"entryTitle": entry
})
else:
return render(request, "encyclopedia/entry.html", {
"entry": markdowner.convert(entryPage),
"entryTitle": entry
})
Clicking the link in entry.html gives me this error:
NoReverseMatch at /wiki/edit/HTML
Reverse for 'edit' with no arguments not found. 1 pattern(s) tried: ['wiki/edit/(?P<entry>[^/]+)$']
If I view page source while on entry.html in the server, that link appears to correctly render the path with the correct value for entryTitle showing up, which I think means that some communication must be happening between the template and urls.py, but then the path isn't found when the link is clicked.
Here is the 'view page source' for entry.html with "HTML" as the value contained by entryTitle:
<button>
Edit Entry
</button>
Does anyone see anything wrong with my code or have ideas how I could troubleshoot? Been stuck on this one for a few days. Thank you
UPDATE here is the edit.html template:
{% extends "encyclopedia/layout.html" %}
{% block title %}
Edit Entry
{% endblock %}
{% block body %}
<h2>Edit encyclopedia entry for {{ entryTitle }}</h2>
<form action="{% url 'edit' %}" method="POST">
{% csrf_token %}
{{ editform }}
<input type="submit" value="Update">
</form>
{% endblock %}

Form post request running wrong view method on Django

I'm trying to clone the Instagram web page using Django(version-3.1).
My Django project has an app called 'post'.
One of its template I have a form which is posting a comment to a post. The form post request should call the path('add_comment/',views.add_comment,name='add_comment'), but It's calling path('<slug:slug>/',views.post_details,name='post_details'), instead. And raising DoesNotExist at /post/add_comment error. I added print() statement at the beginning of both add_comment() and post_details() methods to find out which is running when the request is made. I have no idea what I have done wrong.
The project GitHub link - https://github.com/mirasel/Instagram_Clone
the post_details.html template is -
{% extends 'base.html' %}
{% load static %}
{% block title %} post {% endblock %}
{% block profilephoto %} {{ propic.url }} {% endblock %}
{% block body %}
<div>
<div>
<img src="{{post.image.url}}" alt="post" height="250px" width="250px">
</div>
<div>
<a href="{% url 'instagram:profile' post.uploader %}">
<img src="{{uploader.profile_pic.url}}" alt="{{uploader}}" style="border-radius: 50%;" height="24px" width="24px">
{{ post.uploader }}
</a><br>
<p>{{ post.date_published.date }}</p>
</div>
<div>
<p>{{ post.caption }}</p>
</div>
<div>
<form action="{% url 'post:add_comment' %}" id="comment_form" method="POST">
{% csrf_token %}
<textarea name="comment" id="comment" cols="30" rows="1" placeholder="Write a comment..."></textarea>
<input type="hidden" name="slug" id="slug" value="{{post.slug}}">
<!-- <input type="submit" style="display: none;" name="submit"> -->
</form>
<script>
$(function(){
$("#comment").keypress(function (e) {
if(e.which == 13 && !e.shiftKey) {
$(this).closest("form").submit();
e.preventDefault();
}
});
});
</script>
{% endblock %}
the views.py -
from django.shortcuts import render,redirect
from instagram.views import get_nav_propic,get_profile_details
from .models import UserPost,PostComment,PostLike
from django.http import JsonResponse
def get_post_likes(post):
likes = PostLike.objects.filter(post=post)
total_likes = len(likes)
likers = []
for l in likes:
likers.append(get_profile_details(l.liker))
return {'likers':likers,'total_likes':total_likes}
def get_post_comments(post):
comments = PostComment.objects.filter(post=post)
total_comments = len(comments)
commenter = []
comment = []
for c in comments:
commenter.append(get_profile_details(c.commenter))
comment.append(c.comment)
postcomment = zip(commenter,comment)
return {'post_comment':postcomment,'total_comments':total_comments}
def upload_post(request):
if request.method == 'POST':
image = request.FILES['post_img']
caption = request.POST['caption']
uploader = request.user
UserPost.objects.create(uploader=uploader,image=image,caption=caption)
return redirect('instagram:feed')
else:
context = {
'propic' : get_nav_propic(request.user)
}
return render(request,'post/upload_post.html',context)
def post_details(request,slug):
print('I am here in post details')
post = UserPost.objects.get(slug=slug)
context = {
'propic' : get_nav_propic(request.user),
'post' : post,
'uploader' : get_profile_details(post.uploader),
'LIKES' : get_post_likes(post),
'COMMENTS' : get_post_comments(post),
}
return render(request,'post/post_details.html',context)
def add_comment(request):
print('I am here in add comment')
if request.method == 'POST':
post_slug = request.POST.get('slug')
post = UserPost.objects.get(slug=post_slug)
user = request.user
comment = request.POST.get('comment')
PostComment.objects.create(post=post,commenter=user,comment=comment)
return redirect('post:post_details',slug=post_slug)
the urls.py -
from django.urls import path
from . import views
app_name='post'
urlpatterns = [
path('upload_post/',views.upload_post,name='upload_post'),
path('<slug:slug>/',views.post_details,name='post_details'),
path('add_comment/',views.add_comment,name='add_comment'),
]
The error - Error page
Solved
I had to make the URL path of add_comment as following-
#previous one
path('add_comment/',views.add_comment,name='add_comment'),
#modified one
path('comment/add_comment/',views.add_comment,name='add_comment'),
This is because the pattern for the slug URL and add comment URL were similar.
Because Django will process the urlpatterns sequentially, from docs:
Django runs through each URL pattern, in order, and stops at the first
one that matches the requested URL, matching against path_info.
And '/add_comment' is a valid slug <slug:slug>, so post_details will be called.
So you should keep the definition of the most generic url patterns at last:
urlpatterns = [
path('upload_post/',views.upload_post,name='upload_post'),
path('add_comment/',views.add_comment,name='add_comment'),
path('<slug:slug>/',views.post_details,name='post_details'),
]
Hopefully this will work for you.

How to utilize the Django URL tag?

Sorry for such a beginner question but I have a TemplateSyntaxError on my URL line in my HTML that links to the HTML that allows user to update the article details and I cannot seem to debug it.
Below is article_detail.html where it would have a link to article_update.html
{% extends 'base.html' %}
{% block content %}
<h3>Title: {{object.title}}</h3>
<p>Caption: {{object.caption}}</p>
<p>Activeness: {{object.active}}</p>
Update this Article
{% endblock %}
In the views.py, I have created an article_update_view function as seen below
def article_update_view(request, article_id):
obj = get_object_or_404(Article, id=article_id)
form = ArticleForm(request.POST or None, instance=obj)
if form.is_valid():
form.save()
form = ArticleForm()
context = {
'form': form
}
return render(request, 'article_update.html', context)
and in my app.urls.py, I have written
urlpatterns = [
path('<int:article_id>/update/', article_update_view, name='articleupdate'),
]
Your issue is the way you're passing the object id.
template.html
{% extends 'base.html' %}
{% block content %}
<h3>Title: {{object.title}}</h3>
<p>Caption: {{object.caption}}</p>
<p>Activeness: {{object.active}}</p>
Update this Article # or object.article_id
{% endblock %}

Getting a unexpected link in django template

I'm practicing a simple blog site, where if I clicked in author names, it shows the associated post! If I used two different view function the output is fine but if I implemented in one function, in author's post page it shows a url which should not! The screenshot of the html page:
The Url Link contain author post page link! but according to the code it should display the post link!
Url Link
I'm pasting my all code for better understanding. Thanks in advance!
This is my urls.py:
urlpatterns = [
url('^$', views.url_list, name='url_list'),
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<post>[-\w]+)/$',
views.post_details, name = 'post_links'),
# url(r'^author/(?P<author_slug>[-\w]+)/$', views.author_posts, name = 'url_list_by_author'),
url(r'^author/(?P<author_slug>[-\w]+)/$', views.post_details, name = 'url_list_by_author'),
]
and my view.py is:
def post_details(request, year=None, month=None, day=None, post=None, author_slug=None):
author_post_list = None
if year:
post = get_object_or_404(UrlPost, slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day,
)
if author_slug:
author_post_list = UrlPost.author_manager.author_post(author_slug)
post = None
return render(request, 'detail.html', {'post': post, 'author_post_list': author_post_list})
and html page:
{% extends "base.html" %}
{% block title %}{{post.title}}{% endblock %}
{% block content %}
<h1>{{ post.title|title }}</h1>
<p>{{ post.publish }}</p>
<ul>
{% for author in post.author.all %}
{% if forloop.first %}
<li><h4>Author: </h4></li>
{% endif %}
<li><h4>{{ author|title }}</h4></li>
{% if not forloop.last %}
<li><h4>, </h4></li>
{% endif %}
{% endfor %}
</ul>
<p>{{ post.description }}</p>
Url Link
{% include "author_post.html" %}
{% endblock %}
The first 'url link' you see at the top comes from this line in your html template:
Url Link
All the rest of what is displayed comes from the author_post.html template. The url link is not "additional", actually it's just that everything before is missing.
Probably because the post variable is None. If you actually inspect the generated html, it will look like this:
<h1></h1>
<p></p>
<ul>
</ul>
<p></p>
Url Link
(and the here you will have the contents of author_post)
OK, now for how to solve this: you should not use the same view to display the post and the post author's post. You should create two separate views. Each with its template. Then, assuming you named the new view author_posts in your urls.py:
urlpatterns = [
url('^$', views.url_list, name='url_list'),
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<post>[-\w]+)/$',
views.post_details, name = 'post_links'),
url(r'^author/(?P<author_slug>[-\w]+)/$', views.author_posts, name = 'url_list_by_author'),
]

Categories

Resources