Django Form is not visible in Inherited template - python

I am using template inheritance in my django project. I used form in my base html page and submit button, When i inherit base template to another template form get disappeared but submit button is still there. I have below templates.
base.html
<head>
{% load static from staticfiles %}
<link rel="stylesheet" href="{% static "bootstrap.css" %}">
</script>
</head>
<body>
{% block option %}
<div class="row">
<div class="col-lg-3">
<form method = "post" action="">
{% csrf_token %}
{{form}}
<input type="submit" value="Submit" />
</form>
</div>
</div>
{% endblock %}
<div class="row">
{% block content %}{% endblock %}
</div>
</body>
chart.html
{% extends 'base.html' %}
{% block content %}
<head>
{% load static from staticfiles %}
<link rel="stylesheet" href="{% static "bootstrap.css" %}">
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
</script>
</head>
<div id="container" align="center">
{{ column_chart.as_html }}
{% endblock %}
How can i make form visible there in chart html??
EDIT: Added Views
views.py
def select_chart_form(request):
form = SelectChart(request.POST)
if form.is_valid():
if (str(form.cleaned_data['status']) == '1'):
#print "Hello Naresh reverse('chart1')"
return HttpResponseRedirect('/chart1/')
if (str(form.cleaned_data['status']) == '2'):
return HttpResponseRedirect('/chart2/')
context = {
'form' : form
}
return render(request, 'base.html', context)
def video_by_user(request):
analysis = VideoData.objects.annotate(watches_count = Count('user')).order_by('-watches_count')[:10]
data_source = ModelDataSource(analysis,fields=['video_name', 'watches_count'])
column_chart = gchart.ColumnChart(data_source,options={'title': "Top 10 Videos watched by No. Of Users"})
context = {
"data_source": data_source,
"column_chart": column_chart,
}
return render_to_response('chart.html', context)
I am calling video_by_user method..after click on submit button.

The select_chart_form and video_by_user views are completely separate. The first one renders just base.html, and supplies the form variable when it does so. The second one renders chart.html, which inherits from base.html, but it only supplies the variables needed for chart.html itself: it doesn't provide the form needed for base.html. You will need to supply that in video_by_user.

Related

Making search bar in django

Im trying to make a search bar in django and watched several youtube totorials and none of those worked. What im trying to do is either make a search bar that redirects to articles/what_you_searched_for or if not possible show up results that include search. If someone has enough time they can tell me how to do both :).
in views.py:
def index(request):
queryset = article.objects.all()
number_of_records = article.objects.count()
random_page = random.randint(1,number_of_records)
context = {
"object_list": queryset,
"random_page": random_page
}
# query = ""
# if request.GET:
# query = request.GET['q']
# context['query'] = str(query)
entries = util.list_entries()
return render(request, "encyclopedia/index.html", context)
#{
#"entries": util.list_entries(),
#"random_page": random_page,
#})
def dynamic_articles_view(request, my_id):
obj = article.objects.get(id= my_id)
number_of_records = article.objects.count()
random_page = random.randint(1,number_of_records)
context = {
"object": obj,
"random_page": random_page
}
return render(request, "encyclopedia/article_detail.html", context)
in index.html:
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block body %}
<h1 id="demo" onclick="add_article()">Article</h1>
<ul>
{% for instance in object_list %}
<li>{{instance.title}}</li>
{% endfor %}
</ul>
{% endblock %}
layout.html: ------------ SEARCH BAR HERE ---------
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="{% static 'encyclopedia/styles.css' %}" rel="stylesheet">
</head>
<body>
<div class="row">
<div class="sidebar col-lg-2 col-md-3">
<h2>Wiki</h2>
<form action = "/articles/{{q}}"> __________EXACTLY HERE ________
<input class="search" type="text" name="q" placeholder="Search...">
</form>
<div>
Home
</div>
<div>
<a href = "/new_article" >Create New Article</a>
</div>
<div>
Random Page
</div>
{% block nav %}
{% endblock %}
</div>
<div class="main col-lg-10 col-md-9">
{% block body %}
{% endblock %}
</div>
</div>
</body>
</html>
urls:
from django.contrib import admin
from django.urls import include, path
from encyclopedia import views
from encyclopedia.views import index, new_article, dynamic_articles_view
urlpatterns = [
path('admin/', admin.site.urls),
path('', include("encyclopedia.urls")),
path('new_article/', new_article),
path('home/', index, name = 'home'),
path('articles/<int:my_id>/', dynamic_articles_view, name = 'articless')
]
encyclopedia urls (other folder):
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("", views.new_article, name="new_article")
]
if needed i will comment models and forms but i dont want to make my question to long.
Simplest way is to add a GET form in your template with a search input without setting the action of the form:
<form action="">
<input type="text" name="search" placeholder="Search by title" value="{{request.GET.title}}">
<input type="submit" value="Search">
</form>
Then in the views.py in the you get the value. If it's given, you filter by it:
def dynamic_articles_view(request):
context['object_list'] = article.objects.filter(title__icontains=request.GET.get('search'))
return render(request, "encyclopedia/article_detail.html", context)

TemplateSyntaxError at /accounts/profile/

I got an error:
TemplateSyntaxError at /accounts/profile/
<ExtendsNode: extends "registration/accounts/base.html"> must be the first tag in the template
I wrote base.html:
{% load staticfiles %}
<html lang="ja">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="{% load staticfiles 'bootflat/css/bootflat.min.css' %}">
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<p class="navbar-text">HELLO</p>
{% if user.is_authenticated %}
<p class="navbar-text">{{ user.get_username }}</p>
{% endif %}
</div>
</nav>
<div class="container">
{% block content %}
{% endblock %}
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
</body>
</html>
profile.html is:
{% load staticfiles %}
{% extends "registration/accounts/base.html" %}
{% block content %}
<html lang="ja">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="{% static 'bootflat/css/bootflat.min.css' %}">
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
</head>
<body>
  SEE YOUR PHOTO
<div class="container">
<form action="{% url 'accounts:upload_save' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p>SEND PHOTO</p>
<input type="file" name="files[]" multiple>
<input type="hidden" value="{{ p_id }}" name="p_id">
<input type="submit" value="Upload">
</form>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</body>
</html>
{% endblock %}
I found only base.html was showed accurately, but when I tried base.html inherit profile.html,this error happens. Before,these 2 files are loaded accurately, but when I added href="{% static 'bootflat/css/bootflat.min.css' %}" to profile.html,this error happpens. Why does such an error happen? How can I fix this? I think adding {% load staticfiles %} is right to profile.html,but is it wrong?
You should consider your base.html file as a layout and your profile.html as a template file rendered inside this layout.
For this reason:
load staticfiles block should be inserted in base.html and should be insert in every file where you are loading static assets (see next bullet point)
when you refer to static assets inside src= is enough to load it with static path helper
profile.html should extend the layout base.html and whatever is included in the {% block content %} will be rendered inside the block content tag in your body
base.html
<html lang="ja">
<head>
<meta charset="utf-8">
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'bootflat/css/bootflat.min.css' %}">
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
</head>
<body>
{% block content %}
<!-- your body is fine -->
{% end block %}
</body>
</html>
profile.html
{% extends "registration/accounts/base.html" %}
{% block content %}
SEE YOUR PHOTO
<form action="{% url 'accounts:upload_save' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p>SEND PHOTO</p>
<input type="file" name="files[]" multiple>
<input type="hidden" value="{{ p_id }}" name="p_id">
<input type="submit" value="Upload">
</form>
{% endblock %}
Edit
as remarked by Daniel Roseman
The error says that you must write extends tag first in your template.
You can read more about this in documentation
So, you should write {% extends "registration/accounts/base.html" %} first in profile.html
{% extends "registration/accounts/base.html" %}
{% load staticfiles %}
{% block content %}
...
{% endblock %}
After that all will works fine!

render page is wrong

When I accessed upload_save method,basic.html was showed.
I wrote(changed into) in view.py like
def upload_save(request):
photo_id = request.POST.get("p_id", "")
if (photo_id):
photo_obj = Post.objects.get(id=photo_id)
else:
photo_obj = Post()
files = request.FILES.getlist("files[]")
photo_obj.image = files[0]
photo_obj.save()
return render(request, "registration/accounts/photo.html")
photos = Post.objects.all()
context = {
'photos': photos,
}
return render(request, 'registration/accounts/photo.html', context)
So,I naturally thought when I accessed upload_save method,photo.html would be showed.
In photo.html,I wrote
{% extends "registration/accounts/base.html" %}
{% block body %}
<div class="container">
{% for photo in photos %}
<h2 class="page-header">{{ photo.title }}</h2>
<div class="row">
<div class="col-xs-4">
<img class="img-responsive" src="/media/{{ photo.image1 }}">
</div>
<div class="col-xs-4">
<img class="img-responsive" src="/media/{{ photo.image2 }}">
</div>
<div class="col-xs-4">
<img class="img-responsive" src="/media/{{ photo.image3 }}">
</div>
</div>
<a class="btn btn-primary" href="{% url 'accounts:upload' photo.id %}">UPLOAD</a>
{% endfor %}
</div>
{% endblock %}
I wrote
base.html in photo.html ,but I cannot understand why photo.html's content is not show.
By Google Verification,I found only base.html was showed in my page.(So,photo.html could not be read)
How can I fix this?
You did not provide photos to your template. The {% for photo in photos %} is trying to loop over something that has not been provided. You need to add photos to the template context like so:
# ... rest of your view
photos = Post.objects.all()
context = {'photos': photos}
return render(
request, "registration/accounts/photo.html", context=context
)
Reference: render()
I think you did not include block body in base.html. if not included add these lines in base.html where you want to add photo.html content
{% block body %}
{% endblock %}
base.html should be look like this
{% load staticfiles %}
<html>
<head>
<title>Hello</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link href='//fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{% static 'css/blog.css' %}">
</head>
<body>
<div class="page-header">
<h1>Photo list</h1>
</div>
<div class="content container">
<div class="row">
<div class="col-md-8">
{% block body %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>

Django 1.10 AdminDateWidget() Use in ModelForm

The Django docs aren't clear on using ModelForm. First, how do I set up my urls.py?
I simply do this:
from . import views as music_views
url(r'album/add/$', music_views.AlbumCreate(), name='album-add'),
In my views I'm trying to use the AdminDateWidget:
from . import models as music_models
from django import forms
from django.contrib.admin.widgets import AdminDateWidget
class AlbumCreate(forms.ModelForm):
class Meta:
releasedate = forms.DateField(widget=AdminDateWidget())
model = music_models.Album
fields = ['artist', 'album_title', 'genre', releasedate, 'notes', 'album_logo', 'rating']
My template is:
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2">
{{ field.label_tag }}
</label>
<div class="col-sm-10">
{{ field }}
</div>
</div>
{% endfor %}
My struggle here is that I am getting this error when rendering the page:
Exception Value:
sequence item 0: expected str instance, DateField found
But according to the https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/ docs, DateField is one of the allowable datatypes. So I am obviously doing it wrong somehow, but don't know how to do it right. Can someone help me out on this? I tend to prefer ground up examples to study from, if possible.
At a glance, it seems there are many problems (no form tags in template, fields can only accept strings, etc.) But most importantly for those wanting to use AdminDateWidget: there are a number of extra scripts you need to load which are NOT included in the usual {{ form.media }}.
project/urls.py
from django.conf.urls import include, url
from album.views import album_add
urlpatterns = [
url(r'album/add/$', album_add, name='album-add'),
]
album/models.py
from django import forms
from django.db import models
from django.contrib.admin.widgets import AdminDateWidget
class Album(models.Model):
artist = models.CharField(max_length=30)
releasedate = models.DateField()
class AlbumForm(forms.ModelForm):
releasedate = forms.DateField(widget=AdminDateWidget)
class Meta:
model = Album
fields = ['artist', 'releasedate']
album/views.py
from .models import AlbumForm
from django.shortcuts import render, HttpResponse
def album_add(request):
if request.method == "GET":
form = AlbumForm()
return render(request, 'album/create_album.html', {'form': form})
elif request.method == "POST":
form = AlbumForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse("Saved.")
return render(request, 'album/create_album.html', {'form': form})
album/templates/album/create_album.html
{% load static %}
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
{{ form.media }}
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/base.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}" />
<form>
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="Go!">
</form>
I hope this helps someone!
I found a solution:
admin_forms.py
First add widgets of type AdminDateWidget to your date fields. You will need to assign a custom name as css class attribute (autocomplete=off is optional, disables autofill)
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('date_start', 'date_end',)
widgets = {
'date_start': AdminDateWidget(
attrs={'class': 'picker', 'autocomplete': 'off'}),
'date_end': AdminDateWidget(
attrs={'class': 'picker', 'autocomplete': 'off'}),
}
template.html
Secondly, load necessary resources (datepicker.css)and customise the action of your date fields with class 'picker' or any name you assigned to your css class. Check the code in the script tag. IMPORTANT: For some reason the script tags need to be after the styles to work.
{% extends "admin/base_site.html" %}
{% load i18n %}
{% block content %}
<style rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css" />
<style>
... Other CSS ...
</style>
<script>
grp.jQuery(function () {
grp.jQuery(".picker").datepicker({dateFormat: 'yy-m-d'});
});
</script>
<form action="{{ action_url }}" method="post" id="my_form">
{% csrf_token %}
<section>
<fieldset class="module grp-module">
{% for field in form %}
<label>{{ field.label }}</label>
{{ field }}
{% endfor %}
</fieldset>
</section>
</form>
{% endblock %}
Access to /admin/jsi18n/ requires superuser authentication in Django v.2.0.7. The following line will not work for non-superusers:
<script type="text/javascript" src="/admin/jsi18n/"></script>
The workaround is to copy script from this URL to jsi18n.js (being authenticated as a superuser). Please, note that under each LOCAL_LANGUAGE jsi18n.js has different version, so if you have more then one target LOCAL_LANGUAGE you will need to save different versions of jsi18n.js.

Why are my forms not returning field errors?

Recently I upgraded my django server. Going from 1.2 to a new version. The forms exhibit a strange behavior. When a field is left blank the whole page simply refreshes, rather than showing errors like I remember. What could cause this? What ought I do to fix it?
{%extends "baseAUTH.html" %}
{% block title %}
{{ title }}
{% endblock %}
{% block content %}
{% load adminmedia %}
<script type="text/javascript">
window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";
</script>
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/media/js/core.js"></script>
<link rel="stylesheet" type="text/css" href="/media/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="/media/css/base.css"/>
<link rel="stylesheet" type="text/css" href="/media/css/global.css"/>
<link rel="stylesheet" type="text/css" href="/media/css/widgets.css"/>
{{ form.media }}
<h1>{{ title }}</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table valign=TOP>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>
{% endblock %}
I found the issue. I reverted some changes back and found the point where I broke it. In the following function I tried to abstract
def FormToEmail(request, token, title, subject, message, reciever, attachlist):
if request.method == 'POST':
sender = AddSender(request)
reciever.append(sender)
form = token(request.POST, request.FILES)
if form.is_valid():
mail = EmailMessage(subject, message, sender, reciever)
if len(attachlist) > 0:
for item in attachlist:
if form.cleaned_data[item]:
temp = request.FILES[item]
mail.attach(temp.name, temp.read(), \
temp.content_type)
return SendIt(request, mail)
Here to
else:
form = token()
if request.user.is_authenticated():
return render_to_response('FormTemplate.html', \
{'form': form, 'title' : title}, \
context_instance=RequestContext(request))
else:
return HttpResponseRedirect('/Webtemplate/accounts/login')
here. Into
return RenderFormForAuth(request, token(), title)
with the function defined as
def RenderFormForAuth(request, form, title):
if request.user.is_authenticated():
return render_to_response('FormTemplate.html', \
{'form': form, 'title' : title}, \
context_instance=RequestContext(request))
else:
return HttpResponseRedirect('/Webtemplate/accounts/login')
which broke everything. (I can paste the whole function/ how it's called if need be, but seems like a waste of space.)
Does anyone know why this wouldn't work?

Categories

Resources