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')
)
Related
I have a use case where we need dynamic blocks for a StreamField. Unfortunately this doesn't seem possible, since block types are specified in the model's StreamField field.
I dug through the FieldPanel, StreamBlock and GroupPanel code and cannot clearly find a way to override the available blocks for the StreamField outside the model definition.
This is my current admin EditView, where you can see what I'm trying to accomplish (see the NOTE/FIXME comments below:
class EditProductView(EditView):
def get_edit_handler(self):
summary_panels = [
FieldPanel('title'),
FieldPanel('description'),
FieldPanel('body'),
]
attributes_panel = [
# NOTE/FIXME: This is where we need the custom blocks to load, based
# on `self.instance.product_type`.
FieldPanel('attributes'),
# StreamFieldPanel (which is deprecated) does not work because you can
# only set the blocks within the model, when defining the StreamFieldPanel.
# I would love to be able to do something like:
StreamFieldPanel('attributes', block_types=[
('test', blocks.CharBlock()), # Like this for example
])
]
settings_panels = [
FieldPanel('categories'),
StateMachinePanel('state', sm_prop='sm', heading="State"),
]
return TabbedInterface([
ObjectList(summary_panels, heading='Summary'),
ObjectList(attributes_panel, heading='Attributes'),
ObjectList(settings_panels, heading='Settings'),
]).bind_to_model(self.model_admin.model)
Is it possible to override available StreamField blocks in this way, or are there potential issues with json_field DB integrity?
This wouldn't work, because the StreamField block definition isn't just used for the edit form - any time you access that field, even just to output it on a template, the StreamField needs to look at the block definition to unpack the JSON and return the appropriate Python objects. For example, suppose the database contained:
[{'type': 'test', 'value': 123}]
What should page.attributes[0].value return? If the test block is of type IntegerBlock, it would return 123 - but if it was a PageChooserBlock instead, it would return the Page instance with ID 123. If it was an ImageChooserBlock, it would return the Image instance with ID 123, and so on. In your example, the only way to find out the block type is to call get_edit_handler and construct the entire editing interface as a side effect - this would be mixing up model-level logic with admin interface code, and be massively inefficient just for accessing a single field.
What is the equivalent of ST_GeomFromGeojson() in GeoDjango?
I'm looking for it in GeoDjango's documentation but there's only AsGeoJSON as its output format. This can be done both using annotate and serialize.
But what if I want to have a GeoJson object that I need to turn back to Geom?
Use Case:
geom_test = Geom.objects.filter(poly__within = [ST_GeomFromGeoJSON(d)])
From the docs
GEOSGeometry objects may be created in a few ways. The first is to simply instantiate the object on some spatial input – the following are examples of creating the same geometry from WKT, HEX, WKB, and GeoJSON:
# Other stuff I cut out.
pnt = GEOSGeometry('{ "type": "Point", "coordinates": [ 5.000000, 23.000000 ] }') # GeoJSON
So essentially GEOSGeometry(GeoJSONString)
I had two models called CombinedProduct and CombinedProductPrice which I renamed to Set and SetPrice respectively. I did this by changing their model name in the models.py file and replaced all occurrences of it. This also included renaming a foreignkey field in another model from combined_product to set (pointing to a CombinedProduct).
When running makemigrations django properly detected the renaming and asked if I had renamed all three of those things and I pressed 'yes' for all. However when running 'migrate', after applying some stuff, I get asked:
The following content types are stale and need to be deleted:
product | combinedproduct
product | combinedproductprice
Any objects related to these content types by a foreign key will also
be deleted. Are you sure you want to delete these content types?
If you're unsure, answer 'no'.
I backed up my data and entered 'yes' which deleted all instances of Set (previously CombinedProduct) and SetPrice (previously CombinedProductPrice). If I roll back and tick no, then this question comes up every time I migrate.
This is weird since I don't use any of the django ContentType framework anywhere. When inspecting which fields point to ContentType however I see that auth.permission points to it, and I use permissions for those models. So maybe the deletion cascades from old permissions pointing to the old model names which in turn would delete my instances? If that is the case, how can I prevent this situation?
This is the migration that was generated:
operations = [
migrations.RenameModel(
old_name='CombinedProduct',
new_name='Set',
),
migrations.RenameModel(
old_name='CombinedProductPrice',
new_name='SetPrice',
),
migrations.AlterModelOptions(
name='setprice',
options={'ordering': ('set', 'vendor', 'price'), 'verbose_name': 'Set price', 'verbose_name_plural': 'Set prices'},
),
migrations.RenameField(
model_name='setprice',
old_name='combined_product',
new_name='set',
),
]
If you want to rename your table, please take a look to RenameModel. Yes, Django do not detect the renamed model. So, you need to add it manually.
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/'],
)
))
I want to be able to pass a variable caught in the URL to a Q object for a generic view.
I created a generic view which is imported as my_views.view which handles things like pagination, sorting, filtering etc...
I need to use Q objects because for some pages there will need some OR filters. Each page will also be filtering based on different fields (and models) (hence the generic view).
Example:
view_customers_info = {
"queryset" : Customer.all(),
'qobject': Q(status=stat),
"extra_context" : {
"title" : 'View Customers',
},
'template_name': 'customer/view.html',
}
urlpatterns = patterns('',
url(r'^customer/(?P<stat>\w+)/$', my_views.view, view_customers_info),
)
In this example, this line complains about stat not being a global name:
'qobject': Q(status=stat),
How can I pass the variable caught in the URL to the dictionary view_customers_info?
I can't simply move that Q object into the generic view because other pages will have Q objects like the following:
'qobject': (Q(type=type) | Q(status=stat)),
Thanks.
I think you can only do this by wrapping the generic view with a custom view/function. See also here:
http://docs.djangoproject.com/en/1.1/topics/generic-views/#complex-filtering-with-wrapper-functions
I think your just missing the quotes around the field name.
'qobject': Q(status=("%s" % stat)),