So I am trying to display the first attribute of the first object of my list in django template. I currently have tried
{{objArray.0.name}}
and
{{objArray.0.getName}}
In my template and
class ObjInfo():
def __init__(self,name):
self.name=name
def getName(self):
return self.name
is my class definition. I hard-coded my variables to be declared on any request but I printed it out to be sure it was declared. When I go to the page after running the server, nothing populates. Please help.
EDIT: Section of view is like this(from template):
<button class="accordion">Obj Info</button>
<div class="panel">
<div class="panel-table">
<table id="Obj" style="width:100%">
<tr>
<th>Obj Description</th>
</tr>
<tr>
<td>{{objobjArray.0.name}}</td>
</tr>
</table>
</div>
</div>
There's a few more sections on the table that I ommitted that are static right now, but that is the giist.
Sorry, semi new, here you go:
'''
Created on Jul 9, 2018
#author: packawd
'''
from django.http import HttpResponse
from django.shortcuts import render_to_response,render
from django.template import Context, loader
from django import forms
template_name='App Template.html'
class TicketForm(forms.Form):
ticketNumber=forms.CharField(label="Ticket number", required=False)
assetSerial=forms.CharField(label="Asset S/N")
RadioSerial=forms.CharField(label="Radio S/N")
#Will be used to setup API injection, create object arrays and pass on
#class asassasasasa():
class objInfo():
def __init__(self,name):
self.name=name
def getName(self):
return self.name
def index(request):
if request.method =="POST":
form=TicketForm(request.POST)
if form.is_valid():
#Simple check to see if we are pulling data correctly
"""
print(form.cleaned_data['ticketNumber'])
print(form.cleaned_data['assetSerial'])
print(form.cleaned_data['RadioSerial'])
"""
#Data injection test pt 1
#obj="engine69420"
objobj1=objInfo("Engine1")
objobj2=objInfo("Engine2")
objobjArray=[]
objobjArray.append(objobj1)
objobjArray.append(objobj2)
#Allows us to use the above fields to call an API or something
#We need to switch the below to be CAT endpoint and secure the API
#response = requests.get('http://freegeoip.net/json/%s' % ip_address)
#geodata = response.json()
else:
form=TicketForm()
objobj1=objInfo("Engine1")
objobj2=objInfo("Engine2")
objobjArray=[]
objobjArray.append(objobj1)
objobjArray.append(objobj2)
return render(request, template_name, {'form': form, 'objobjarray':objobjArray,})
It looks like the name you are using in creating the context objobjarray doesn't match the name you are using in your template ecmobjArray.
So what this turned out being is that I was trying to reference objobjArray instead of objobjarrayin my context. It'd probably be handy for me in the future to use the same name for both in this area:
'objobjarray':objobjArray
Related
I'm currently attempting to learn how to use django to build a website but my input data in the models is not showing up properly
'''
from django.db import models
class products(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class typeWork(models.Model):
work = models.CharField(max_length = 255)
hoursWorked = models.IntegerField()
number_in_stock = models.IntegerField()
daily_rate = models.FloatField()
genre = models.ForeignKey(products, on_delete=models.CASCADE)
'''
models.py
'''
from django.urls import path
from . import views
urlpatterns = [
path('hello/', views.hello, name='hello')
]
'''
urls.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import typeWork
def hello(request):
products2 = {typeWork.objects.all()}
return render(request, 'index.html', {products2})
views.py is slightly altered as i was messing with it in order to try and fix it the image shows the code with no alterations and my original issue arising from that code
views.py
<table class="table">
<thead>
<tr>
<th>Work</th>
<th>Type of Work</th>
<th>Hours needed</th>
</tr>
</thead>
<tbody>
{% for products2 in products%}
<tr>
<td>{{products2.work}}</td>
<td>{{products2.genre}}</td>
<td>{{products2.hoursWorked}}</td>
</tr>
{% endfor %}
</tbody>
indes.html is also slightly altered the image will show the original code before i tried fixing it again
index.html
Actual error and what it does show currently
You can try passing your products2 variable through a so-called "context dictionary".
Updated version of views.py:
I'm currently attempting to learn how to use django to build a website but my input data in the models is not showing up properly
from django.shortcuts import render
from django.http import HttpResponse
from .models import typeWork
def hello(request):
products2 = typeWork.objects.all()
context = {"products2": products2}
return render(request, 'index.html', context)
You had some idea on how to pass these variables when you put the {} symbols, but only adding names between these symbols will pass a set. A dictionary would mean the curly braces + a set of key-value pairs.
The main idea is, everytime you're trying to pass data to a view, you'll need to do it via a dictionary. The key you're using will also be used in the template. By replacing your code with the one I wrote, you're going to be okay because your template is iterating through something called products2.
I want to use Chart.js as the plotting tool and write a Django view that will run an ORM query, get some data, turn it into JSON, pass the JSON data to the Django context, and render the plot in the Django template without too much fuss. I am hoping to do this as simply as possible.
I was able to do something like this with Highcharts-django but it is prohibitively expensive.
This is roughly what I'd like to do:
(1) Get data loaded in 'get_context_data' via an ORM query in views.py and format the data into json using 'local_utils.py' method generate_chart(data)
from local_utils import generate_chart
class MyView(TemplateView):
template_name = "template.html"
def get_context_data(self, *args, **kwargs):
data_source = MyModel.objects.fitler(start_date__gte=start_date).values()
my_chart = generate_chart(data_source)
context['my_chart'] = my_chart
(2) Pass the data to the method generate_chart(data_source) and return a LineChartJSONView object (or something)
from random import randint
from django.views.generic import TemplateView
from chartjs.views.lines import BaseLineChartView
def generate_chart(data_source):
class LineChartJSONView(BaseLineChartView):
def get_labels(self):
"""Return labels for the x-axis."""
return data_source.values_list('x-data', flat=True)
def get_providers(self):
"""Return names of datasets."""
return ['data']
def get_data(self):
"""Return datasets to plot on y-axis."""
return data_source.values_list('y-data', flat=True)
line_chart = TemplateView.as_view(template_name='line_chart.html')
line_chart_json = LineChartJSONView.as_view()
return line_chart_json
(3) Pass the context object my_chart to template.html
<head>
{{ my_chart|load_data_to:"container" }}
</head>
<body>
{# Other stuff #}
{% if chart %}
<div id='container'>Chart will go here</div>
{% endif %}
{# Other stuff #}
</body>
(4) Plot something like this: https://github.com/peopledoc/django-chartjs#3-get-a-chartjs-line-chart
I have seen the usage in the docs where the only thing happening in a View is the plotting. However, I'd like to have the plot embedded within a TemplateView. Is this possible with Chart.js? If yes, how?
I get stuck. I try to display each time a other table in django with the same def in my view.py code.
First problem is I can't transfer the string which I enter in the url to a model.
For example if I type 0.0.0.0:8000/polls/Cashflows I wanna display the table Cashflows of my db.
from django.http import HttpResponse
from django.template import loader
from django.apps import apps
from .models import Cashflows,Garbage,Inputacturial
def index(request):
list_cashflows=Cashflows.objects.all()
template=loader.get_template('polls/index.html')
context={'list_cashflows':list_cashflows,}
return HttpResponse(template.render(context,request))
def detail(request, table):
#model = apps.get_model('polls', 'table')
#model=apps.get_model ( 'polls',table.split('.',1))
model=Cashflows
liste_column=model.objects.all()
b=model._meta.get_fields()
#b=a[:]
liste_fields=list(b)
template=loader.get_template('polls/index2.html')
context={'liste_column':liste_column,'liste_fields':liste_fields,}
return HttpResponse(template.render(context,request))
I try different options but none of these really work for.
My next problem is to display these different tables.
I try to start with the field names.
<table>{% for item in liste_fields%}
<tr><th>liste_fields.item</th>
</tr>
{% endfor %}
</table>
It's just give me three rows with liste.fields.item and not columns with each field. Can you help me?
You have of use the o method verbose_name
For example:
list_fields = [field.verbose_name for field in Cashflows._meta.get_fields() if not field.is_relation or field.one_to_one or (field.many_to_one and field.related_model)]
https://docs.djangoproject.com/en/2.0/ref/models/meta/#migrating-from-the-old-api
I have invite form with two fields defined as person and email as follows:
class InviteForm(Form):
person = TextField("person", validators=[validators.Required("Please enter persons name.")])
email = EmailField("email", validators=[validators.Required("Please enter valid email."), validators.Email("Please enter valid email.")])
def validate(self):
return validate_form(self)
Where validate_form function is a cusotm validator which check few conditions for invite.
My requirement is to allow users to invite more than one person at a time. To achieve this I have added jquery function which replicates these fields in html form and allow to invite multiple people.
But the problem is in my view function when I extract results from post request it gives only first persons information. How can I get all the persons details. My view is defined as follows:
#app.route("/invite", methods=["GET", "POST"])
def invite():
invite_form = InviteForm()
if invite_form.validate_on_submit():
print invite_form.person
print invite_form.email
This gives only one field, instead of array of fields.
Is this possible with python wtf? How?
What you're looking for is FormField which lets you build a list of the WTF Fields (or groups even).
Here's a simple example-- it'll render three string fields as a html list because that's the minimum required. If you want to add extras via javascript, then just adhere to the same naming scheme, in the case below, a fourth would have a name of person-3.
from flask import Flask, render_template_string
from flask.ext.wtf import Form
from wtforms import FieldList, StringField
app = Flask(__name__)
app.secret_key = 'TEST'
class TestForm(Form):
person = FieldList(StringField('Person'), min_entries=3, max_entries=10)
foo = StringField('Test')
#app.route('/', methods=['POST', 'GET'])
def example():
form = TestForm()
if form.validate_on_submit():
print form.person.data
## [u'One', u'Two', u'Three']
return render_template_string(
"""
<form method="post" action="#">
{{ form.hidden_tag() }}
{{ form.person }}
<input type="submit"/>
</form>
""", form=form)
if __name__ == '__main__':
app.run(debug=True)
Do not understand how to pass data obtained from form.data in view as choices to form field. I would really appreciate any help.
So, here is what I am doing: I choose data using checkboxes at page, and then I need to display chosen data (their names) at the same page with additional textfield near each. Later all textfields must be filled and 'names' and inserted data must be sent to server.
As I understand for this I need to render data with textfield using form. I suppose it could be this one:
forms.py
import methods
class MultiTextField(SelectMultipleField):
widget = widgets.TableWidget()
option_widget = widgets.TextInput()
class SelectedForm(Form):
choices = methods.selected()
value = MultiTextField('value',choices = choices)
views.py
from forms import ...
selected_data = {}
def return_selected():
return selected_data
methods.py
from views import return_selected
def selected():
data = return_selected()
choices = []
for key, value in data.iteritems():
for item in value:
choices.append((item, key))
return choices
Variable selected_data stores data that were chosen through other form.
If I run this code I got error ImportError: cannot import name return_selected. Probably it is because I import views in methods, methods in forms and forms in views o.O
I see no other way how to make what I need, but it does not work as it is.
Well, I found how to pass choices.
forms.py
class MultiTextField(SelectMultipleField):
widget = widgets.TableWidget()
option_widget = widgets.TextInput()
class SelectedForm(Form):
name = MultiTextField()
views.py
#app.route('/home', methods=['GET', 'POST'])
def show_work():
selected = SelectedForm(request.form)
choices = []
for key, value in selected_data.iteritems():
choices.append((key, value))
selected.name.choices = choices
return render_template('home.html', selected=selected)
It is possible to add form choices in views with selected.name.choices = choices.
But this form puts data in strange way:
home.html
<form name="selected" action="{{url_for('selected_work', url='result') }}" method="post">
<p> {{selected.name}}</p>
<input type="submit" value="Calculate">
</form>
in choices was lets say: [(1,"Apple"), (2,"Apple")] but html show label 'Apple' and near it textfield with inserted number 1 and again label 'Apple' with number 2 inserted in textfield.
When I submit form ofcourse it sends inserted data in textfield, which is ['1', '2']. But somehow I need obtain: [(Apple, 1 and value inserted in textfield),(Apple, 2, inserted value)].
You have a circular dependency. Views import forms, which imports methods, which imports forms.
But your proposed solution is extremely dangerous. You are storing data at module level, which is absolutely not thread-safe and will lead to information leaking between users. Do not do this. Store the data in the session, which is per-user.
Thank you Daniel for your advice about session. I store chosen data in session now.
Here is how I solved my task. I decided not to use wtforms form for rendering data chosen with checkboxes. I keep all choices in session
views.py
import methods
from forms import ...
def make_record(works):
if session['data']:
if not works:
pass
else:
for work in works:
session['data'].append(work)
else:
session['data'] = [works]
#app.route('/home', methods=['GET', 'POST'])
def show_work():
demount = DemountForm(request.form)
tile = TileForm(request.form)
chosen = []
for each in session['data']:
chosen.append(each)
selected = methods.get_selected(chosen)
return render_template('home.html', demount=demount, tile=tile, selected = selected)
#app.route('/home/<path:url>', methods=['GET', 'POST'])
def select_work(url):
db = url
if db:
form = DemountForm(request.form)
work = form.name.data
make_record(work)
return redirect(url_for('show_work'))
methods.py
def get_selected(ids):
selected = {}
for each in ids:
data = db_session.query(Work.name, Work.dimension).filter(Work.id==each).all()
data = data[0]
selected[each] = data
return selected
home.html
{% if selected %}
<div id="chosen">
<form action="/home">
{% for key, value in selected.iteritems() %}
{{value[0]}}<input type="text" id="{{key}}">{{value[1]}}<br>
{% endfor %}
<input type="submit" value="Submit">
</form>
</div>
{% endif %}
In such way I obtained what I needed. On one page I got menu with checkboxes and div which display choices and textfields near each to insert additional data.