django-admin-tools 3 column layout not working - django

I'm using django-admin-tools 0.4.
Following the docs here so that I can get a 3 column layout.
I have managed to get the page to space correctly for 3 columns but the Modules can't move over to the 3rd column.
I can only drag from the left column to the middle but not right.
How can I get the modules to move between the 3 columns?
My dashboard.py can be viewed here.
I've attached a screenshot to show what result I have.

The main issue was that admin_tools_dashboard_preferences needs to be truncated(almost for every change being made to the dashboard.)
Also the first snippet of code on the documentation page didn't even work for me. I took snippets from other parts of the docs and they seemed to work no problems.
In the end my example dashboard looks something like this.
Remember to truncate your preferences.
class MyDashboard(Dashboard):
columns = 3
def __init__(self, **kwargs):
Dashboard.__init__(self, **kwargs)
# will only list the django.contrib.auth models
self.children += [
modules.ModelList('Authentication', ['django.contrib.auth.*',])
]
self.children.append(modules.Group(
title="My group",
display="tabs",
children=[
modules.AppList(
title='Administration',
models=('django.contrib.*',)
),
modules.AppList(
title='Applications',
exclude=('django.contrib.*',)
)
]
))
self.children.append(modules.LinkList(
layout='inline',
children=(
{
'title': 'Python website',
'url': 'http://www.python.org',
'external': True,
'description': 'Python programming language rocks !',
},
['Django website', 'http://www.djangoproject.com', True],
['Some internal link', '/some/internal/link/'],
)
))

Related

How to enter a list in WTForms?

What I'm trying to do
I'm trying to enter a list of tags in flask that should become passable as a list but I can't figure out how to do it in flask, nor can I find documentation to add lists (of strings) in flask_wtf. Has anyone have experience with this?
Ideally I would like the tags to be selectively delete-able, after you entered them. So that you could enter.
The problem
Thus far my form is static. You enter stuff, hit submit, it gets processed into a .json. The tags list is the last element I can't figure out. I don't even know if flask can do this.
A little demo of how I envisioned the entry process:
How I envisioned the entry process:
The current tags are displayed and an entry field to add new ones.
[Tag1](x) | [Tag2](x)
Enter new Tag: [______] (add)
Hit (add)
[Tag1](x) | [Tag2](x)
Enter new Tag: [Tag3__] (add)
New Tag is added
[Tag1](x) | [Tag2](x) | [Tag3](x)
Enter new Tag: [______]
How I envisioned the deletion process:
Hitting the (x) on the side of the tag should kill it.
[Tag1](x) | [Tag2](x) | [Tag3](x)
Hit (x) on Tag2. Result:
[Tag1](x) | [Tag3](x)
The deletion is kind of icing on the cake and could probably be done, once I have a list I can edit, but getting there seems quite hard.
I'm at a loss here.
I basically want to know if it's possible to enter lists in general, since there does not seem to be documentation on the topic.
Your description is not really clear (is Tag1 the key in the JSON or is it Tag the key, and 1 the index?)
But I had a similar issue recently, where I wanted to submit a basic list in JSON and let WTForms handle it properly.
For instance, this:
{
"name": "John",
"tags": ["code", "python", "flask", "wtforms"]
}
So, I had to rewrite the way FieldList works because WTForms, for some reason, wants a list as "tags-1=XXX,tags-2=xxx".
from wtforms import FieldList
class JSONFieldList(FieldList):
def process(self, formdata, data=None):
self.entries = []
if data is None or not data:
try:
data = self.default()
except TypeError:
data = self.default
self.object_data = data
if formdata:
for (index, obj_data) in enumerate(formdata.getlist(self.name)):
self._add_entry(formdata, obj_data, index=index)
else:
for obj_data in data:
self._add_entry(formdata, obj_data)
while len(self.entries) < self.min_entries:
self._add_entry(formdata)
def _add_entry(self, formdata=None, data=None, index=None):
assert not self.max_entries or len(self.entries) < self.max_entries, \
'You cannot have more than max_entries entries in this FieldList'
if index is None:
index = self.last_index + 1
self.last_index = index
name = '%s-%d' % (self.short_name, index)
id = '%s-%d' % (self.id, index)
field = self.unbound_field.bind(form=None, name=name, id=id, prefix=self._prefix, _meta=self.meta,
translations=self._translations)
field.process(formdata, data)
self.entries.append(field)
return field
On Flask's end to handle the form:
from flask import request
from werkzeug.datastructures import ImmutableMultiDict
#app.route('/add', methods=['POST'])
def add():
form = MyForm(ImmutableMultiDict(request.get_json())
# process the form, form.tags.data is a list
And the form (notice the use of JSONFieldList):
class MonitorForm(BaseForm):
name = StringField(validators=[validators.DataRequired(), validators.Length(min=3, max=5)], filters=[lambda x: x or None])
tags = JSONFieldList(StringField(validators=[validators.DataRequired(), validators.Length(min=1, max=250)], filters=[lambda x: x or None]), validators=[Optional()])
I found a viable solution in this 2015 book, where a tagging system is being build for flask as part of a blog building exercise.
It's based on Flask_SQLAlchemy.
Entering lists therefore is possible with WTForms / Flask by submitting the items to the database via, e.g. FieldList and in the usecase of a tagging system, reading them from the database back to render them in the UI.
If however you don't want to deal with O'Rielly's paywall (I'm sorry, I can't post copyrighted material here) and all you want is a solution to add tags, check out taggle.js by Sean Coker. It's not flask, but javascript, but it does the job.

Field from database showing up as the word "None" on frontend template but exist in the database

I've encountered the weirdest thing while developing a django-python web app.
I have a field in my database that I want to display on the frontend. The field is a MultiSelectField and the list is populated from a list
models.py
# Other service areas
other_areas = MultiSelectField(choices = SERVICE_AREAS, max_length=360,
default=None, null=True)
My SERVICE_AREAS is created by a function like this:
def get_service_areas():
#SERVICE_AREAS = [('None', '-------------')]
SERVICE_AREAS = []
sas = service_area.objects.all()
for s in sas:
SERVICE_AREAS.append((s.name, s.name))
return SERVICE_AREAS
I have a form from where I select the other "service areas" and everything is submitted to my database correctly (in pgadmin I see the correct values)
proof of ok values in DB
Then on the frontend side in my template i have this code to present the data:
index.html
<div class="email" style="padding-top: 10px;">{{c.service_area}}- {{c.service_area.said}} , Other SAID's: {{c.other_areas}}</div>
The weird part about this is that when the data actually show on my screen it turns up as the word "None" as many times is there are comma seperated values in that field. (If there are 3 service areas it will come up as None, None, None, if 4 service areas: None, None, None, None etc.)
The rest of my data shows up correctly in the template. I'm kinda stumped and any ideas are welcome.
example output for the image I added above:
I have two values in the other_areas field (43006,43001) and it shows up like this
There really isn't much source code here to go off of. But, it is clearly telling you that there is nothing there. You could not be passing the object to the front-end from your views which would make those template tags show None. Since you don't show what your model actually is, what data you are rendering from your views, nobody here can necessarily help you. I would recommend you post code so we can further understand how to help you.

Create multiple (two) source with chartit in Django

I'm using chartit in a django project.
I have a models (ReadingSensor) with the following attributes:
id_sensor
date_time
value
I want to create a line chart with several lines for different id_sensors
for example:
ReadingSensor.objects.filter(id_sensor=2)
ReadingSensor.objects.filter(id_sensor=1)
For a single model we have:
ds = DataPool(
series=
[{'options': {
'source': MonthlyWeatherByCity.objects.all()},
'terms': [
'month',
'houston_temp',
'boston_temp']}
])
cht = Chart(
datasource = ds,
series_options =
[{'options':{
'type': 'line',
'stacking': False},
'terms':{
'month': [
'boston_temp',
'houston_temp']
}}],
chart_options =
{'title': {
'text': 'Weather Data of Boston and Houston'},
'xAxis': {
'title': {
'text': 'Month number'}}})
Documentation: http://chartit.shutupandship.com/docs/
I consulted the documentation but found no suggestive example to help me.
Can someone help me?
Actually the example is on the site you provide, please check this link: http://chartit.shutupandship.com/demo/chart/multi-table-same-x/
The idea is just to add more items with options and terms to the series list when constructing DataPool object and adjust the terms in series_options when constructing Chart object accordingly.
Then you may find it's helpful to adjust the field name for the case when two data sources have the fields with the same name, the detailed document regarding to this issue is here: http://chartit.shutupandship.com/docs/apireference.html#datapool

Several Fields on a Single Row while using CBVs & Bootstrap

I am working on a project using Bootstrap and making use of Class Based Views. The forms that are rendered automagically are quite nice. But I want to make one simple change. Given a model that has city, state & zip fields, I want the form to render all three off those fields on the same row.
Name [ ]
Addr [ ]
City [ ] State [ ] Zip [ ] <-- 3 fields, 1 row
I assume this is a pretty common task that has an elegant solution, but I have not found it. I was hoping django-crispyforms Row('city', 'state', 'zip'), would do in the Layout but that did not work.
I haven't used crispy forms in a while but I believe with bootstrap you have to do something like example below because you cannot simply insert form elements into a row:
Row(
Div('city', css_class='span4'),
Div('state', css_class='span4'),
Div('zip', css_class='span4')
)

Django admin doesn't show translated enumerations in list view under Python 2.3

When using localized list of "choices" for a model field, the admin doesn't show the translated values in the list view.
Short example:
from django.utils.translation import ugettext_lazy as _
class OrderStates:
STATES = (
(STATE_NEW, _("New")),
(STATE_CANCELLED, _("Cancelled")), )
class Order(models.Model):
state = models.IntegerField(choices=OrderStates.STATES)
# ..
class OrderAdmin(admin.ModelAdmin):
list_display = [ 'id', 'state', 'address', 'user']
# ..
admin.site.register(Order, OrderAdmin)
The localized versions of "New" and "Cancelled" show up correctly in the front-end and in the admin form when editing an order. But in the admin list view I get blank fields - regardless of the language I switch to, including English. Column names are fine.
This only happens with Python 2.3 (talk about niche questions). The choices display correctly everywhere with Python 2.5. I don't get any errors or warnings in neither.
Tried using ugettext instead of ugettext_lazy for the options, which didn't work. ugettext_noop sort of works - it at least shows the original english versions instead of blank fields.
Am I doing something wrong or is this a bug?
This is probably a bug somewhere in Django, not calling force_unicode on the item correctly. The original code you pasted is correct. You don't mention what Django version you're using, so I'd reccomend trying the latest 1.0.3 or 1.1 release to see if that happens to fix it, else check the ticket tracker to see if it's already been reported (note that if it hasn't been fixed yet it probably won't be at all, since 1.1 is the last version to support 2.3).
try using:
import gettext as _
Though, that may break if some of your translations use non-ascii values. Actually, this should have been fixed some time ago, see Ticket #5287.
Hope this helps.