Bottle.py - split string array (CSV) - bottle

I have a small web demo pulling data from into a CSV file, which I want to display on a web page. I plan to use Bottle.py, but I cannot split the string into an array. There will be multiple lines in the CSV file, which I will read in split and then create a table.
from bottle import run, debug, template, get, redirect, request, response, static_file, route, os, sys
LOG_FILENAME = "data.csv"
#route('/hello/<name>')
def index(name):
readfiledata()
print(reader)
array = reader.split(',')
return template('<b>Hello {{name}}</b>!', name=reader)

Maybe something like this (using csv module from the Standard Library):
import csv
from bottle import route, jinja2_template
#route('/csv')
def show_csv():
with open('data.csv') as fo:
csv_reader = csv.reader(fo)
table = [row for row in csv_reader]
return jinja2_template('templ.html', table=table)
templ.html (I'm using Jinja2 templates which I prefer over Bottle's built-in templating language):
<table style="width:100%">
<tr>
{# Table header #}
<th>Foo</th>
<th>Bar</th>
<th>Baz</th>
</tr>
{% for row in table %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Related

Using Django, how do I set a ModelForm field value dynamically in the template?

I'm trying to utilize a checkbox field to create a model instance for a user selected favorite. The last piece I need in order for this to work properly is to set the default value in one of the form fields equal to the value in a loop. Would I do this with the initialize argument, in the views.py file, in the form itself, or in the template? Here is the associated code:
Apologies for the HTML class tags
models.py
class ReportDirectory(models.Model):
report_name = models.CharField(max_length=300, unique=True, blank=False)
report_desc = models.TextField()
report_type = models.CharField(max_length=300)
report_loc = models.TextField()
slug = models.SlugField(unique=True, max_length=300)
last_update = models.DateTimeField(null=True)
main_tags = models.CharField(max_length=300)
# Renames the item in the admin folder
def __str__(self):
return self.report_name
class Favorite(models.Model):
directory_user = models.ForeignKey(User, on_delete=models.CASCADE)
user_report = models.ForeignKey(ReportDirectory, on_delete=models.CASCADE)
favorited = models.BooleanField(default=False)
def __str__(self):
return str(self.directory_user)+" - "+str(self.user_report)
forms.py
from django import forms
from .models import Favorite
class FavoriteForm(forms.ModelForm):
class Meta:
model = Favorite
fields = '__all__'
widgets = {
'favorited': forms.CheckboxInput(attrs={
'type':'checkbox',
'name':'checkbox',
'onchange':'submit()'
})
}
views.py
from django.shortcuts import render,redirect
from django.views import generic
from .models import ReportDirectory, Favorite
from django.contrib.auth.models import User
from .forms import FavoriteForm
def report_directory(request):
favorite = Favorite.objects.filter(directory_user=request.user.id, favorited=True)
reports = ReportDirectory.objects.exclude(favorite__directory_user=request.user.id, favorite__favorited=True)
favform = FavoriteForm(initial={'directory_user':request.user},)
context = {
'reports':reports,
'favorite':favorite,
'favform':favform
}
if request.method == 'POST':
form = FavoriteForm(request.POST)
if form.is_valid():
form.save()
return redirect('/report_directory')
return render(request, 'counter/report_directory.html',context)
html
<thead>
<tr>
<th class="gls-table-expand">Favorite</th>
<th onclick="sortTable(1)" class="gls-table-expand">Report Type</th>
<th onclick="sortTable(2)" class="gls-table-expand">Report Name</th>
<th class="gls-table-expand">Report Description</th>
<th onclick="sortTable(3)" class="gls-table-expand">Last Updated</th>
<th class="gls-table-expand">Main Tags</th>
<th onclick="sortTable(4)" class="gls-table-expand">View Count</th>
</tr>
</thead>
<tbody id="myTable">
{% for r in reports.all %}
<tr report-name="{{ r.report_name }}">
<td>
<form method="POST">
{% csrf_token %}
{{ favform.favorited }}
</form>
</td>
<td><span><img img width="20" height="20"
{% if r.report_type == 'Tableau' %}
src=" {% static 'images/tableau_icon.svg' %}"
{% elif r.report_type == 'Excel' %}
src=" {% static 'images/excel_icon.svg' %}"
{% elif r.report_type == 'Box' %}
src=" {% static 'images/excel_icon.svg' %}"
{% elif r.report_type == 'Internal Report' %}
src=" {% static 'images/www_icon.svg' %}"
{% endif %}
></span> {{ r.report_type }}</td>
<td>{{ r.report_name }}</td>
<td>{{ r.summary }}</td>
<td><p class="gls-text-meta gls-margin-remove-top">{{ r.last_update_format }}</p></td>
<td>{{ r.main_tags }}</td>
<td>{% get_hit_count for r %}</td>
</tr>
{% endfor %}
</tbody>
I found a solution to dynamically iterate through the template and complete the ForeignKey (selection) field. I needed to set the for iterator equal to the selection option
<form method="POST" id="{{ r.report_name }}">
{% csrf_token %}
<p hidden>
{{ favform.directory_user }}
<select name="user_report" required="" id="id_user_report">
<option value="{{ r.id }}" selected></option>
</select>
</p>
{{ favform.favorited }}
</form>
I feel like I'm working against Django forms, however, and not with the infrastructure...

Python Django edit data in database by forms (django v.1.9.4)

My goal is add data to database via form and make them editable via edit form.
My error:
Exception Type: NoReverseMatch at /testtable/car/new/
Exception Value: Reverse for 'car_list' with arguments '()' and keyword arguments '{'pk': 2}' not found. 0 pattern(s) tried: []
and next problem is how to make a link to edit data
in template/car_list.html to car_edit.html.
<td>Delete</td>
<td>Edit Delete</td>
When I type manually in Explorer http://localhost:8000/testtable/car/1/ it works, I see details of first article in database, but forms with pk arguments doesnt work.
MyApp/testtable/models.py
from django.db import models
import datetime
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class TableParemeters(models.Model):
author = models.ForeignKey('auth.User')
car_brand = models.CharField(max_length=20)
car_type = models.CharField(max_length=20)
car_colour = models.CharField(max_length=20)
car_fuel = models.CharField(max_length=20)
car_trans = models.CharField(max_length=20)
car_license_plate = models.CharField(max_length=20)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return "%s %s" % (self.car_brand, self.car_type)
MyApp/testtable/views.py
from django.shortcuts import redirect, get_object_or_404, render_to_response, render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.template import loader
from django.views import generic
from django.utils import timezone
from django.template import RequestContext
from django.core.context_processors import csrf
from django.contrib.auth.models import User
from .models import TableParemeters
from .forms import CarForm
def car_list(request):
cars = TableParemeters.objects.all().order_by('id')
return render(request, 'testtable/car_list.html', {'cars': cars})
def car_detail(request, pk):
car = get_object_or_404(TableParemeters, pk=pk)
return render(request, 'testtable/car_detail.html', {'car': car})
def car_new(request):
if request.method == "POST":
form = CarForm(request.POST)
if form.is_valid():
car = form.save(commit=False)
car.save()
return redirect ('car_list', pk=car.pk)
else:
form = CarForm()
return render(request, 'testtable/car_new.html', {'form': form})
def car_edit(request, pk):
car = get_object_or_404(TableParemeters, pk=pk)
if request.method == "POST":
form = CarForm(request.POST, instance=car)
if form.is_valid():
car = formsave(commit=False)
car.save()
return redirect('car_detail', pk=car.pk)
else:
form = CarForm(instance=car)
return render(request, 'testtable/car_edit.html', {'form': form})
MyApp/testtable/forms.py
from django import forms
from .models import TableParemeters
class CarForm(forms.ModelForm):
class Meta:
model = TableParemeters
fields = '__all__'
MyApp/testtable/urls.py
from django.conf.urls import include, url
from . import views
app_name = 'testtable'
urlpatterns = [
#login
#url(r'^$', views.login_page, name='login'),
#logout
#carlist url
url(r'^$', views.car_list, name='car_list'),
#detail car url
url(r'^car/(?P<pk>\d+)/$', views.car_detail, name='car_detail'),
#add new car to list url
url(r'^car/new/$', views.car_new, name='car_new'),
#edit car in the list
url(r'^car/(?P<pk>\d+)/edit/$', views.car_edit, name='car_edit'),
]
MyApp/testtable/template/testtable/car_list.html
{% extends 'testtable/base.html' %}
{% block content %}
<table class="table table-striped">
<tbody>
<tr>
<th>ID</th>
<th>Brand</th>
<th>Type</th>
<th>Colour</th>
<th>Fuel</th>
<th>Transmition</th>
<th>License Plate</th>
<th>Created Date</th>
<th>Author</th>
<th></th>
</tr>
{% for testtable in cars %}
<tr>
<td>{{ testtable.car_id }}</a></td>
<td>{{ testtable.car_brand }}</a></td>
<td>{{ testtable.car_type }}</td>
<td>{{ testtable.car_colour }}</td>
<td>{{ testtable.car_fuel }}</td>
<td>{{ testtable.car_trans }}</td>
<td>{{ testtable.car_license_plate }}</td>
<td>{{ testtable.created_date }}</td>
<td>{{ testtable.author }}</td>
<td>Delete</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
I mean, that car_list not need pk and django can't found any url for car_list with parameter.
Maybe you can try replace line:
return redirect ('car_list', pk=car.pk)
with:
return redirect ('car_list')

Render custom entity type field in form (Symfony)

I got stuck while trying to customize the rendering of a specific field in my form.
It looks like this:
$builder->add('players', 'entity', array(
'class' => 'Acme\Bundle\Entity\Player',
'expanded' => true,
'multiple' => true,
'required' => false,
));
The form itself is beeing rendered with a simple:
{% block form_content %}
{% form_theme form 'AcmeBundle:Form:fields_child.html.twig' %}
{{ form_widget(form) }}
{% endblock %}
Now inside fields_child.html.twig i'm extending from another form template but there is nothing special there.
My HTML looks like this:
Players:
- [checkbox-input] 1
Where 1 equals the id of the only player in the database. However instead of rendering the ID im trying to render his picture and full name after the checkbox.
I have tried many combinations of the form theming to override it but failed each time.
Could someone post the twig block to render what i want here?
Thanks
You have to create custom form field type together with custom widget template for it.
http://symfony.com/doc/current/cookbook/form/create_custom_field_type.html
I recently ran into this problem (was a little bit different situation. I needed to show products as table with checkboxes..), Form's child data always returned null value that's why I ended up with this (dirty:)) solution:
Controller action:
...
$productRepository = $entityManager->getRepository('VendorMyBundle:Product');
$products = [];
$formChildren = $productListForm->createView()->children;
foreach ($formChildren['products'] as $formProduct) {
$formProductId = $formProduct->vars['value'];
$productEntity = $productRepository->find($formProductId);
$products[$formProductId] = $productEntity;
}
...
return $this->render('TEMPLATE', [
'productListForm' => $productListForm->createView(),
'products' => $products,
]);
Template:
...
{% for productForm in productListForm.products %}
{% set id = productForm.vars.value %}
<tr>
<td class="check">
{{ form_widget(productForm) }}
</td>
<td class="photo">
{% if products[id].getImages().isEmpty() == false %}
{% set productImage = products[id].getImages().first() %}
<img src="{{ productImage.getWebPath() | imagine_filter('st_product_cabinet_thumbnail') }}" />
{% else %}
<span class="no-image">No image</span>
{% endif %}
</td>
<td class="title">
{{ products[id].getName() }}
</td>
<td class="status">
{{ products[id].getStatusName(products[id].getStatus()) }}
</td>
<td class="price">
<ul>
{% for productPrice in products[id].getPrices() %}
<li>{{ productPrice.getValue() ~ ' ' ~ productPrice.getCurrencyCode() }}</li>
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
...

How to customize the data-prototype attribute in Symfony 2 forms

Since umpteens days, I block on a problem with Symfony 2 and forms.
I got a form of websites entities. "Websites" is a collection of website's entities and each website contains two attributes : "type" and "url".
If I want to add more of one website in my database, I can click on a "Add another website" link, which add another website row to my form. So when you click on the submit button, you can add one or X website(s) at the same time.
This process to add a row use the data-prototype attribute, which can generate the website sub-form.
The problem is that I customize my form to have a great graphic rendering... like that :
<div class="informations_widget">{{ form_widget(website.type.code) }}</div>
<div class="informations_error">{{ form_errors(website.type) }}</div>
<div class="informations_widget">{{ form_widget(website.url) }}</div>
<div class="informations_error">{{ form_errors(website.url) }}</div>
But the data-prototype doesn't care about this customization, with HTML and CSS tags & properties. I keep the Symfony rendering :
<div>
<label class=" required">$$name$$</label>
<div id="jobcast_profilebundle_websitestype_websites_$$name$$">
<div>
<label class=" required">Type</label>
<div id="jobcast_profilebundle_websitestype_websites_$$name$$_type">
<div>
<label for="jobcast_profilebundle_websitestype_websites_$$name$$_type_code" class=" required">label</label>
<select id="jobcast_profilebundle_websitestype_websites_$$name$$_type_code" name="jobcast_profilebundle_websitestype[websites][$$name$$][type][code]" required="required">
<option value="WEB-OTHER">Autre</option>
<option value="WEB-RSS">Flux RSS</option>
...
</select>
</div>
</div>
</div>
<div>
<label for="jobcast_profilebundle_websitestype_websites_$$name$$_url" class=" required">Adresse</label>
<input type="url" id="jobcast_profilebundle_websitestype_websites_$$name$$_url" name="jobcast_profilebundle_websitestype[websites][$$name$$][url]" required="required" value="" />
</div>
</div>
</div>
Does anyone have an idea to make that hack ?
A bit old, but here is a deadly simple solution.
The idea is simply to render the collection items through a Twig template, so you have full ability to customize the prototype that will be placed in your data-prototype="..." tag. Just as if it was a normal, usual form.
In yourMainForm.html.twig:
<div id="collectionContainer"
data-prototype="
{% filter escape %}
{{ include('MyBundle:MyViewsDirectory:prototype.html.twig', { 'form': form.myForm.vars.prototype }) }}
{% endfilter %}">
</div>
And in MyBundle:MyViewsDirectory:prototype.html.twig:
<div>
<!-- customize as you wish -->
{{ form_label(form.field1) }}
{{ form_widget(form.field1) }}
{{ form_label(form.field2) }}
{{ form_widget(form.field2) }}
</div>
Credit: adapted from https://gist.github.com/tobalgists/4032213
I know this question is quite old, but I had the same problem and this is how I soved it. I'm using a twig macro to accomplish this. Macros are like functions, you can render them with different arguments.
{% macro information_prototype(website) %}
<div class="informations_widget">{{ form_widget(website.type.code) }}</div>
<div class="informations_error">{{ form_errors(website.type) }}</div>
<div class="informations_widget">{{ form_widget(website.url) }}</div>
<div class="informations_error">{{ form_errors(website.url) }}</div>
{% endmacro %}
now you can render this macro wherever you want. Note that information_prototype() is just the name of the macro, you can name it whatever you want. If you want to use the macro to render the given items and the prototype the same way, do something like this:
<div class="collection" data-prototype="{{ _self.information_prototype(form.websites.vars.prototype)|e }}">
{% for website in form.websites %}
{{ _self.information_prototype(website) }}
{% endfor %}
<button class="add-collection">Add Information</button>
</div>
form.websites.vars.prototype holds the prototype data of the form with the prototype_name you specified. Use _self.+macroname if you want to use the macro in the same template.
You can find out more about macros in the Twig documentation
You probably have found out since but here is the solution for others.
Create a new template and copy/paste this code in it:
https://gist.github.com/1294186
Then in the template containing the form you want to customise, apply it to your form by doing this:
{% form_theme form 'YourBundle:Deal:Theme/_field-prototype.html.twig' %}
I've run into similar problem recently. Here's how you can override the collection prototype without having to explicitly set it in the html:
{% set customPrototype %}
{% filter escape %}
{% include 'AcmeBundle:Controller:customCollectionPrototype.html.twig' with { 'form': form.collection.vars.prototype } %}
{% endfilter %}
{% endset %}
{{ form_label(form.collection) }}
{{ form_widget(form.collection, { 'attr': { 'data-prototype': customPrototype } }) }}
You can do whatever you want then in your custom twig. For example:
<div data-form-collection="item" data-form-collection-index="__name__" class="collection-item">
<div class="collection-box col-sm-10 col-sm-offset-2 padding-top-20">
<div class="row form-horizontal form-group">
<div class="col-sm-4">
{{ form_label(form.field0) }}
{{ form_widget(form.field0) }}
</div>
<div class="col-sm-3">
{{ form_label(form.field1) }}
{{ form_widget(form.field1) }}
</div>
<label class="col-sm-3 control-label text-right">
<button data-form-collection="delete" class="btn btn-danger">
<i class="fa fa-times collection-button-remove"></i>{{ 'form.collection.delete'|trans }}
</button>
</label>
</div>
</div>
Useful when you only have to do it in specific places and don't need a global override that's applicable to all collections.
I know that answer is very late but it maybe useful for visitors.
on your theme file you can simply use one block for rendering every collection entry of websites widget as following:
{% block _jobcast_profilebundle_websitestype_websites_entry_widget %}
<div class="informations_widget">{{ form_widget(form.type.code) }}</div>
<div class="informations_error">{{ form_errors(form.type) }}</div>
<div class="informations_widget">{{ form_widget(form.url) }}</div>
<div class="informations_error">{{ form_errors(form.url) }}</div>
{% endblock %}
also create theme block for your collection widget row as following:
{% block _quiz_question_answers_row %}
{% if prototype is defined %}
{%- set attr = attr | merge({'data-prototype': form_row(prototype) }) -%}
{% endif %}
{{ form_errors(form) }}
{% for child in form %}
{{ form_row(child) }}
{% endfor %}
{% endblock %}
now the prototype and the rendered collection entry will be the same.
I had a somewhat similar issue. You might have to tweak this to work for your case, but someone may find it helpful.
Create a new template file to hold your custom form 'theme'
./src/Company/TestBundle/Resources/views/Forms/fields.html.twig
Normally, you can use the form_row function to display a field's label, error, and widget. But in my case I just wanted to display the widget. As you say, using the data-prototype feature would also display the label, so in our new fields.html.twig type your custom code for how you want the field to look:
{% block form_row %}
{% spaceless %}
{{ form_widget(form) }}
{% endspaceless %}
{% endblock form_row %}
I removed the container div, and the label and error, and just left the widget.
Now in the twig file that displays the form, simply add this after the {% extends ... %}
{% form_theme form 'CompanyTestBundle:Form:fields.html.twig' %}
And now the form_widget(form.yourVariable.var.prototype) will only render the field and nothing else.
Application wide form theming will be applied to the prototype.
See Making Application-wide Customizations
Here is sample code for custom data-prototype:
{{ form_widget(form.emails.get('prototype')) | e }}
where emails — your collection.
To customize differently existing collection items VS prototype, you can override collection_widget like this:
{%- block collection_widget -%}
{% if prototype is defined %}
{%- set attr = attr|merge({'data-prototype': form_row(prototype, {'inPrototype': true} ) }) -%}
{% endif %}
{{- block('form_widget') -}}
{%- endblock collection_widget -%}
And then in your custom entry:
{% block _myCollection_entry_row %}
{% if(inPrototype is defined) %}
{# Something special only for prototype here #}
{% endif %}
{% endblock %}
If you do not need to define a template system-wide, simply set a template in your twig template, and ask twig to use it.
{# using the profiler, you can find the block widget tested by twig #}
{% block my_block_widget %}
<div >
<p>My template for collection</p>
<div >
{{ form_row(form.field1)}}
</div>
<div>
{{ form_row(form.field2)}}
</div>
</div>
{% endblock %}
{% form_theme form.my_collection _self %}
<button data-form-prototype="{{ form_widget(form.my_collection.vars.prototype) )|e }}" >Add a new entry</button>
There are two blocks that you can possibly target to add a custom theme to a collection field:
_myCollection_row and _myCollection_entry_row
_myCollection_row - renders the whole collection.
_myCollection_entry_row - renders a single item.
The prototype relies on _myCollection_entry_row so if you theme _myCollection_row only your theme will appear in the form, but not the prototype. The prototype uses _myCollection_entry_row.
So it's best to theme _myCollection_entry_row first, and then theme _myCollection_row only if required. BUT - if you theme _myCollection_row make sure it calls _myCollection_entry_row to render each item in your collection.
This post focuses on using pre-existing conventions within the twig template.
Basing off "How to Embed a Collection of Forms" from the Symfony Cookbook (http://symfony.com/doc/master/cookbook/form/form_collections.html), you can just enter whatever html_escaped form data you wish in the data-prototype (maybe considered a hack, but works wonderfully) and only pages using that template will change.
In the example, they tell you to put:
<ul class="tags" data-prototype="{{ form_widget(form.tags.vars.prototype)|e }}">
...
</ul>
This can be successfully replaced with something such as:
<table class="tags" data-prototype="<tr> <td><div><input type="text" id="task_tags__name__tagId" name="task[tags][__name__][taskId]" disabled="disabled" required="required" size="10" value="" /></div></td> <td><div><input type="text" id="task_tags__name__tagName" name="task[tags[__name__][tagName]" required="required" value="" /></div></td></tr>">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr>
...pre existing data here...
</tr>
</table>
Where the data-type attribute of the table with the class "tags" above is the html-escaped version (and line breaks removed though spaces are ok and required) of:
<tr>
<td><div><input type="text" id="task_tags__name__tagId" name="task[tags][__name__][taskId]" disabled="disabled" required="required" size="10" value="" /></div></td>
<td><div><input type="text" id="task_tags__name__tagName" name="task[tags[__name__][tagName]" required="required" value="" /></div></td>
</tr>
...but you must also adjust the javascript in the example to add tr's instead of li elements:
function addTagForm(collectionHolder, $newLinkTr) {
...
// Display the form in the page in an tr, before the "Add a question" link tr
var $newFormTr = $('<tr></tr>').append(newForm);
...
};
...
// setup an "add a tag" link
var $addTagLink = $('Add a tag');
var $newLinkTr = $('<tr></tr>').append($addTagLink);
...
For me, the next step is figuring out how to define the prototype in an external file that I can somehow call in the twig template for the data-prototype that dynamically works with the form. Something like:
<table class="tags" data-prototype="{{somefunction('App\Bundle\Views\Entity\TagsPrototypeInTable')}}">
So if one of the other posts is describing this and I am too dense or if someone knows how to do such, say so!
There is a link to something from gitHub from Francois, but I didn't see any explanation so I think that is probably the more dynamic method I'll get to one of these near-future days.
Peace,
Steve
Update:
One can also use just parts of the prototype:
data-prototype="<tr> <td>{{ form_row(form.tags.vars.prototype.tagId) | e }}</td> <td>{{ form_row(form.tags.vars.prototype.tagName) | e }}</td></tr>"
Where the data-type attribute of the table with the class "tags" above is the html-escaped version (and line breaks removed though spaces are ok and required) of:
<td>{{ form_row(form.tags.vars.prototype.tagId) | e }}</td>
<td>{{ form_row(form.tags.vars.prototype.tagName) | e }}</td>
(I used http://www.htmlescape.net/htmlescape_tool.html.)
Symfony will replace the information between the {{}} with an html_escaped (because of the "|e") rendered field when the page is rendered. In this way, any customization at the field-level is not lost, but! you must manually add and remove fields to the prototype as you do so with the entity :)

Variable 'name' in a django template form

I have the following template, which has both an "add" and "delete" button:
<tr>
<td>Position</td>
<td>{{ form.position }}<input type="submit" value="add" , name='add'/></td>
</tr>
<tr>
<td> </td>
<td>
{% for position in positions %}
{{ position}}<input type="submit" value="Delete", name="delete-position.{{ position }}"/>
{% endfor %}
</td>
</tr>
How would I construct the views.py function to find the name value of the Delete submit button? I currently have:
try:
request.POST['add']
positions.append(request.POST['position'])
return render_to_response('registration/getting_started_info1.html', {'form': form, 'positions': positions}, context_instance = RequestContext(request))
except:
if 'delete-position' in request.POST:
positions.remove(### how to get name of Delete submit? ###)
return render_to_response('registration/getting_started_info1.html', {'form': form, 'positions': positions}, context_instance = RequestContext(request))
Also, is there a better way to construct the view/template so I can use an if...else instead of a try...except ?
First, you should probably do this:
if request.method == "POST":
if 'add' in request.POST.keys():
positions.append(...)
return render_to_response(...)
else:
for k, v in request.POST.items():
if k.startswith('delete-position'):
positions.remove(k)
return render_to_response(...)
That should help with what you're asking... however, I'm not sure if it's the easiest method to do what you're trying to do.
Save the positions in the session.
Your try-catch is kind of weird. You should probably be submitting delete requests to a different view.
But as to how you can get the delete-position vars, it's easy:
def delete(request):
if request.method == "POST":
for key in request.POST.keys():
if key.startswith('delete-position'):
positions.remove(request.POST[key])