I am trying to update my homepage whenever a new "article" is added, however it is giving me this error whenever I try to update the page using my updateHomepage view it doesn't work and I get the error
TemplateSyntaxError at /
Could not parse the remainder: ' 'update_homepage'' from 'url 'update_homepage''
I am very new to django so any help with this would be amazing.
My Views.py
def index(request):
articles = Article.objects.all()
context = {'articles': articles}
return render(request, 'able/homepage.html', context)
def updateHomepage(request, pk):
form = EditorForm(instance=task)
context = {'form': form}
article = Editor.objects.get(id=pk)
return render(request, 'able/update_homepage.html', context)
if request.method == 'POST':
form = EditorForm(request.POST, instance=task)
if form.is_valid():
form.save()
return redirect('/')
def editorview(request):
editor = EditorForm
context = {'editor': editor}
return render(request, 'able/editor.html', context)
if request.method == 'POST':
form = EditorForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
urls.py
urlpatterns = [
path('', views.index, name='homepage'),
path('editor/', views.editorview),
path('update_homepage/<str:pk>/', views.updateHomepage, name='update_homepage')
]
homepage.html
<h1>My Blog</h1>
{% for article in articles %}
<div class="article">
{% csrf_token %}
<h1>{{ article.title }}</h1>
<h3>{{ article.text }}</h3>
</div>
{% endfor %}
Update
update_homepage.html
<h3>Update Homepage</h3>
<form action="" method="POST">
{% csrf_token %}
{{form}}
<input type="submit">
</form>
Related
I am trying to build a CRM in Django and in doing so I am trying to add a place to add comments to a lead. I created a form and upon submitting a comment I get directed to the 401 page where I am greeted with an error. On the 401 page it references my form.save() in my views. Please help.
401 Error
"Field 'id' expected a number but got 'some'."
. I will post my code below
Below is my info view which is used to display information about a particular lead
def info(request, pk):
info = lead.objects.get(id=pk)
form = lead_comment()
if request.method == 'POST':
form = lead_comment(request.POST)
if form.is_valid():
form.save()
return redirect('info.html')
context={'info':info, 'form': form}
return render(request, 'info.html', context)
My URLS
from django.urls import path
from . import views
urlpatterns = [
path('', views.dashboard, name='dashboard'),
path('leads/', views.leadsPage, name='leads'),
path('docs/', views.docsPage, name='docs'),
path('add-lead/', views.addLead, name='add-lead'),
path('leads/<str:pk>/', views.info, name='description'),
]
My info.html
{% include 'navbar.html' %}
<body class="dash">
<div class="navdash">
<div class="container-lead">
<div class="lead-space">
<h2>{{ info.first }} {{ info.last }}</h2>
<h5>Phone number: {{ info.phnum }}</h5>
<h5>Email: {{ info.email }}</h5>
</div>
<body>
<form method="POST" action="">
{% csrf_token %}
{{ form }}
<input type = "submit" value = "Submit" />
</form>
</body>
</div>
</div>
</body>
My lead model where I have am initializing comment
class lead(models.Model):
first=models.CharField(max_length=20)
last=models.CharField(max_length=20)
email=models.CharField(max_length=30)
phnum=models.CharField(max_length=10)
associate=models.ForeignKey(agent, on_delete=models.CASCADE, default='some' )
comment=models.CharField(max_length=500, blank=True, null=True)
def __str__(self):
return self.first + ' ' + self.last
My Form
class lead_comment(ModelForm):
class Meta:
model=lead
fields=['comment']
Try adding the following lines to your info views:
def info(request, pk):
i = lead.objects.get(id=pk)
form = lead_comment(instance=i)
if request.method == 'POST':
form = lead_comment(request.POST, instance=i)
if form.is_valid():
form.save()
return redirect('info.html')
context={'i':i, 'form': form}
return render(request, 'info.html', context)
So the django file is not showing the form and at first, I got angry at that so I just used HTML code to create a form but I realized that when I submit it on the form it does not send it to where I want it to send. I was just wondering if you could help. I think the problem with the file is between the relationship between util.py file and the index.html file but I can't see it for some reason.
Thank you!!
util.py file
class Form(forms.Form):
searched = forms.CharField(max_length=128, help_text="Please enter the category name.")
def get_name(request):
if request.method == 'POST':
form = Form(request.POST)
if form.is_valid():
searched = form.cleaned_data['searched']
return searched
else:
form = Form
return render(request, "wiki/index.html", {
"form" : form
})
wiki.urls.py - main urls file
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include("encyclopedia.urls")),
path('wiki/', include("encyclopedia.wurls"))
]
encyclopedia.urls file
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
views.py file
from django.shortcuts import render
from . import util
def index(request):
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries(),
"lookUp": util.get_name(request)
})
def title(request, name):
return render(request, "encyclopedia/titlePage.html", {
"entries": util.list_entries(),
"name": name,
"entry": util.get_entry(name)
})
index.html file
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block formsearch %}
<form action="/wiki/{{lookUp}}" method="post">
{% csrf_token %}
{{ lookUp }}
<input type="submit" value="Submit">
</form>
{% endblock %}
{% block body %}
<h1>All Pages</h1>
<ul>
{% for entry in entries %}
<li> <a href= "/wiki/{{entry}}" > {{ entry }} </a> </li>
{% endfor %}
</ul>
{% endblock %}
Take away this from util.py:
def get_name(request):
if request.method == 'POST':
form = Form(request.POST)
if form.is_valid():
searched = form.cleaned_data['searched']
return searched
else:
form = Form
return render(request, "wiki/index.html", {
"form" : form
})
and instead add this to views.py:
def index(request):
if request.method == 'POST':
form = Form(request.POST)
if form.is_valid():
searched = form.cleaned_data['searched']
return searched
else:
form = Form
return render(request, "wiki/index.html", {
"form" : form
})
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries(),
"lookUp": util.get_name(request)
})
I'm trying to make a website that lets visitors search for books using another search engine. I have a script that takes a query, and returns some HTML with the results of the search, but I'm struggling to make a front end for this. I am using django because it seemed like the best option when I started, but now I am going in circles and I can't figure out how to make this thing - I'm just getting overwhelmed because the different tutorials and documentation that I'm reading all go into the advanced stuff before I can get the basic thing working.
Do I need separate search and results templates? Right now I'm getting the error The view book_search.views.search didn't return an HttpResponse object. It returned None instead.
How can I fix this error and/or design this whole thing better?
Here's what I have so far (the script that returns the results in html is pull.py):
The views and urls are from inside the book_search app.
views.py:
from django.shortcuts import render
from django.http import HttpResponse
from . import pull
from .forms import SearchForm
def index(request):
return HttpResponse("Welcome to the index page")
def test_search(request):
context = {'query': 'test query'}
return render(request, 'book_search/search.html', context)
def search(request):
if request.method == "GET":
form = SearchForm(request.GET)
if form.is_valid():
query = form.cleaned_data['query']
results = pull.main(query)
context = {'query': query, 'form': form, 'results': results}
return render(request, 'book_search/results.html', context)
apps.py:
from django.apps import AppConfig
class BookSearchConfig(AppConfig):
name = 'book_search'
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('index', views.index, name='index'),
path('test', views.test_search, name='test_search'),
path('', views.search, name='search'),
]
forms.py:
class SearchForm(forms.Form):
query = forms.CharField(label='Search', max_length=200)
template base.html:
<html>
<head>
</head>
<body>
<form method="GET" action="/search/">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
{% block content %}{% endblock %}
</body>
</html>
template results.html:
{% block content %}
{% results %}
{% endblock content %}
Since we guessed that form isn't valid (because no POST handler - you do not send anything to the form) and wrong indentation gives None response, now you can fix reference before assignment:
def search(request):
if request.method == "GET":
form = SearchForm()
context = {'form': form}
elif request.method == "POST":
form = SearchForm(request.POST)
if form.is_valid():
query = form.cleaned_data['query']
results = pull.main(query)
context = {'query': query, 'form': form, 'results': results}
return render(request, 'book_search/results.html', context)
and render errors in results.html template by putting this:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
I'm aware my issue may be to lack of Django knowledge, but I'm trying to pass user input from one form in a view, to another view which will then render that view's HTML page with the given input.
I'm redirected fine, but the data is not being displayed. I believe it has something to do with the contexts not being passed properly, but I do not understand what is wrong or how to fix it.
views.py
def home_view(request, *args, **kwargs):
print(args, kwargs)
print(request.user)
if request.method == 'POST':
form2 = PostForm(request.POST)
if form2.is_valid():
post = form2.save(commit=False)
post.poster = request.user
post.content = form2.cleaned_data.get('content')
post.title = form2.cleaned_data.get('title')
post.syntax = form2.cleaned_data.get('syntax')
post.public = form2.cleaned_data.get('public')
rand = str(uuid.uuid4())[:6]
while Paste.objects.filter(generated_url=rand):
rand = str(uuid.uuid4())[:6]
post.generated_url = rand
form2.save()
context = {
"poster_name": post.poster,
"paste_contents": post.content,
"paste_title": post.title,
"paste_syntax": post.syntax,
"paste_visible": post.public
}
return HttpResponseRedirect(reverse('details', args=(post.generated_url,)), context)
else:
form2 = PostForm()
return render(request, "home.html", {'form2': form2})
def detail_view(request, *args, **kwargs):
if request.user.is_authenticated:
if request.method=='POST':
form3 = PostForm(request.POST)
url = form3.generated_url
your_posts = Paste.objects.get(url)
context = {
'form3': form3
}
return render(request, "paste_detail.html", context)
return render(request, "paste_detail.html", {'form3': form3})
home.html
{% extends "base.html" %}
{% block content %}
<h1>Your user is {{ request.user }}</h1>
<div class="submit_form">
<form action="" method="POST">
{% csrf_token %}
{{ form2.as_p }}<br>
<input type="submit" name="submit" value="Paste" id="submit">
</div>
{% endblock content %}
And paste_detail.html
{% extends "base.html" %}
{% block content %}
<!--<h1>Name of post: {{ post.title }}</h1>-->
<p>Content of post:</p>
I AM REDIRECTED
<h1>Name of post: {{ form2.title }}</h1>
<p>Content of post:</p>
<p>{{form3.content|linebreaks}}</p>
{{ form3.poster }}
{{ form3.contents }}
{{ form3.title }}
{{ form3.syntax }}
{{ form3.visible }}
{% endblock %}
edit:
views.py
def home_view(request, *args, **kwargs):
if request.method == 'POST':
form2 = PostForm(request.POST)
if form2.is_valid():
post = form2.save(commit=False)
post.poster = request.user
post.save()
rand = str(uuid.uuid4())[:6]
while Paste.objects.filter(generated_url=rand):
rand = str(uuid.uuid4())[:6]
post.generated_url = rand
# return HttpResponseRedirect(reverse('details', args=(post.generated_url,)), context)
return redirect('detail', rand)
else:
form2 = PostForm()
return render(request, "home.html", {'form2': form2})
def detail_view(request, custom_uuid):
post = get_object_or_404(Paste, pk=pk)
return render(request, "paste_detail.html", {'post': post})
#return render(request, "paste_detail.html", {'form3': form3})
paste_detail.html
{% extends "base.html" %}
{% block content %}
<p>Content of post:</p>
I AM REDIRECTED
<h1>Name of post: {{ post.title }}</h1>
<p>Creator of post:</p> {{ post.poster }}
<p>Content of post:</p> {{ post.content }}
<p>Title of post:</p> {{ post.title }}
{{ post.syntax }}
{{ post.visible }}
{% endblock %}
And urls.py
...
urlpatterns = [
path('home/', home_view, name='home'),
path('contact/', contact_view, name='contact'),
path('admin/', admin.site.urls, name='admin'),
path('about/', about_view, name='about'),
url(r'^signup/$', views.signup, name='signup'),
path('paste_list/', paste_list_view, name='paste_list'),
url(r'^$', home_view),
#url(r'^(?P<rand_url>\S{6})/$', detail_view, name='details'),
path('detail/<str:custom_uuid>/', detail_view, name='detail'),
path('accounts/', include('django.contrib.auth.urls')),
]
There are several problems in your code. Lets fix them one by one(Please check the code comments for explanation):
In home_view you are doing some redundant codes, you can simplify like this:
from django.shortcuts import redirect
...
if request.method == 'POST':
form2 = PostForm(request.POST)
if form2.is_valid():
post = form2.save(commit=False) # it is not saved in db
post.poster = request.user
rand = str(uuid.uuid4())[:6]
while Paste.objects.filter(generated_url=rand).exists():
rand = str(uuid.uuid4())[:6]
post.generated_url = rand
post.save() # it will save all information to DB, so you don't need to call form2.cleaned_data.get(..)
return redirect('details', custom_uuid=rand) # I am redirecting to `detail_view`. here `rand` is the random uuid of the post which is saved in db
else:
form2 = PostForm()
return render(request, "home.html", {'form2': form2}) # rendering form for GET request
Now lets update detail view to catch the redirection:
from django.shortcuts import get_object_or_404
def detail_view(request, custom_uuid):
post = get_object_or_404(Post, generated_url=custom_uuid) # getting the post object from database using model.
return render(request, "post_detail.html", {'post': post}) # sending data in context to template
# url
path('detail/<str:custom_uuid>/', detail_view, name='detail') # here <str:custom_uuid> will catch the uuid sent in the url
# HTML
{% extends "base.html" %}
{% block content %}
<p>Content of post:</p>
I AM REDIRECTED
<h1>Name of post: {{ post.title }}</h1> // <-- getting this context from view
<p>Content of post:</p>
<p>{{post.content|linebreaks}}</p>
{{ post.poster }}
{{ post.contents }}
{{ post.title }}
{{ post.syntax }}
{{ post.visible }}
{% endblock %}
Here get_object_or_404 gets the entry for model Post, if its not found then throws 404 error.
Contexts are per-request. Once your view has returned, the context no longer exists. When you do a redirect, you are finishing that request/response cycle and starting another one with your detail view. None of the context will carry over.
Instead, you need a way to store pertinent information between requests. One fairly simple way to do this is storing data in the session.
For example, you might store title in a session like this in home_view:
request.session['title'] = post.title
And then in your detail_view view, you could add it to your context:
context = {
'title': request.session.get('title')
}
Check out the Django documentation on sessions for more info: https://docs.djangoproject.com/en/2.1/topics/http/sessions/
Hi i try add comment to my django blog procject and i get OSError: [Errno 22] Invalid argument: "C:\Users\marci\PycharmProjects\08.04\blog\templates\"
so my urls
path('<int:a_id>/addcomment', views.addcomment, name='addcomment'),
views.py
def addcomment(request, a_id):
article = get_object_or_404(Articles,id=a_id)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.article = article
comment.save()
return HttpResponseRedirect('/article/%s' % a_id)
else:
form = CommentForm()
template = 'addcomment.html'
context = {'form': form}
return render_to_response(request,template,context)
addcomment.html
{% extends 'main.html' %}
{% block article %}
<form action="/article/{{ article.id }}/addcomment/" method="post" class="form-horizontal well">{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-inverse" name="submit" value="Dodaj komentarz" />
</form>
{% endblock %}
thx
You should be using render instead of render_to_response. You should also include article in the template context if you use it. Deindent the template and contect lines, so that the view works for invalid post requests.
def addcomment(request, a_id):
article = get_object_or_404(Articles,id=a_id)
if request.method == 'POST':
...
else:
form = CommentForm()
template = 'addcomment.html'
context = {'form': form, 'article': article}
return render(request, template, context)