I'm attempting to create a search page for a database that I am maintaining by creating a dynamically maintained select box of all of the unique values of a few of my fields.
After much time and thought, I've decided that the best way to create a search form for my database would be to do so in views, resulting in something equivalent to this:
search_form = modelform_facotry(my_model,
fields=('field_one', 'field_two',),
widgets={'field_one': Select(choices=((datum.field_one, datum.field_one) for datum in my_model.objects.distinct('field_one'))),
'field_two': Select(choices=((datum.field_two, datum.field_two) for datum in my_model.objects.distinct('field_two'))),
}
)
This works great! Except that I can't figure out how to include a blank option... The choices have to be created in a loop like that, so I can't just add a blank choice as many solutions suggest.
I've been pulling out my hair over this for a while now, because it seems like adding a blank option to a select widget would be an easy fix, but evidently not. Any help would be appreciated.
Edit: I should add that my fields are all CharFields
After playing around with it for a while, I discovered what I needed to do:
FIELD_ONE_CHOICES = (('', '-----'),)
for datum in my_model.objects.distinct('field_one'):
FIELD_ONE_CHOICES += ((datum.field_one, datum.field_one),)
FIELD_TWO_CHOICES = (('', '-----'),)
for datum in my_model.objects.distinct('field_two'):
FIELD_TWO_CHOICES += ((datum.field_two, datum.field_two),)
search_form = modelform_factory(my_model,
fields=('field_one', 'field_two'),
widgets={'field_one': Select(choices=FIELD_ONE_CHOICES),
'field_two': Select(choices=FIELD_TWO_CHOICES),
}
)
Tuples can be frustrating...
Related
Basically what the title says: Flask-Admin is not including some columns in create / edit but are included in the list.
Flask-Admin is just not including 2 of the columns in the create or edit fields, but is including them in the list. Any idea why this might be happening? The two columns not included are flag_type and filters
filters = Column(JSONSchema(FeatureFlagsFiltersSchema),
doc="This field should contain filters for the feature flag applicability")
flag_type = Column(UnicodeTextEnum(FeatureFlagType), index=True,
doc="Specifies whether the feature flag is FE or BE related")
There are many other columns that are showing up fine such as name, ect.
I've tried doing something like below
form_create = ['code', 'label', 'doc', 'blanket_on_off_null', 'warn_after', 'ticket_id', 'usage_info', 'flag_type']
to force those columns to show up but they don't seem to be working. Thanks for the help! I can post more code if needed
Probably due to the complexity of these fields, flask-admin can't figure out what kind of form widget it is supposed to render for them. You can try adding them in form_extra_fields with proper field types e.g.:
from wtforms.fields import TextAreaField
class TestModelView(ModelView):
form_extra_fields = {
'filters': TextAreaField('filters')
}
I am trying to display a map of my data based on a search. The easiest way to handle the map display would be to serialized the queryset generated by the search, and indeed this works just fine using . However, I'd really like to allow for multiple searches, with the displayed points being shown in a user chosen color. The user chosen color, obviously cannot come from the database, since it is not a property of these objects, so none of the aggregators make sense here.
I have tried simply making a utility class, since what I really need is a somewhat complex join between two model classes that then gets serialized into geojson. However, once I created that utility class, it became evident that I lost a lot of the benefits of having a queryset, especially the ability to easily serialize the data with django-geojson (or natively once I can get 1.8 to run smoothly).
Basically, I want to be able to do something like:
querySet = datumClass.objects.filter(...user submitted search parameters...).annotate(color='blue')
Is this possible at all? It seems like this would be more elegant and would work better than my current solution of a non-model utility class which has some serious serialization issues when I try to use python-geojson to serialize.
The problem is that extra comes with all sorts of warning about usefulness or deprecation... But this works:
.extra(select={'color': "'blue'"})
Notice the double quotes wrapping the string value.
This translates to:
SELECT ('blue') AS "color"
Not quite sure what you are trying to achieve, but you can add extra attributes to your objects iterating over the queryset in the view. These can be accessed from the template.
for object in queryset :
if object.contition = 'a'
object.color = 'blue'
else:
object.color = 'green'
if you have a dictionary that maps fields to values, you can do things like
filter_dictionary = {
'date__lte' : '2014-03-01'
}
qs = DatumClass.objects.filter(**filter_dictionary)
And qs would have all dates less than that date (if it has a date field). So, as a user, I could submit any key, value pairs that you could place in your dictionary.
I have two fields that run throughout a website that I would like to match so that when a user inputs a value either of the fields, it will match the other field. I'm using Sitecore Rocks and am trying to use a query to do this.
select ##h1#, ##Title#
from /sitecore/Content/Home//*[##h1# !="##Title#"];
update set ##h1# = ##Title# from /sitecore/Content/Home//*[##Title# = "<id>"];
What am I missing here?
This article talks about tapping in to the item:saving event which allows you to compare the fields values of the item before and after the changes:
http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2010/11/Intercepting-Item-Updates-with-Sitecore.aspx
Using this, you can determine which field has been amended, then change the other to match.
I've had to do something similar to this when a new field was added, and we wanted to set the initial value equal to an existing field. It may be a bug in Sitecore Rocks, but I found it would only update a field when a static value was part of the query.
When I ran ##h1# = ##Title#, the query analyzer would return the correct number of items updated, but no values were actually updated. However, ##h1# = '<id>' worked perfectly. After trying a number of things, I found this did what I wanted.
update set ##h1# = '' + ##Title# from /sitecore/Content/Home//*[##Title# = "<id>"];
I hope that helps.
I have a page that displays multiple Formsets, each of which has a prefix. The formsets are created using formset_factory the default options, including extra=1. Rows can be added or deleted with JavaScript.
If the user is adding new data, one blank row shows up. Perfect.
If the user has added data but form validation failed, in which case the formset is populated with POST data using MyFormset(data, prefix='o1-formsetname') etc., only the data that they have entered shows up. Again, perfect. (the o1 etc. are dynamically generated, each o corresponds to an "option", and each "option" may have multiple formsets).
However if the user is editing existing data, in which case the view populates the formset using MyFormset(initial=somedata, prefix='o1-formsetname') where somedata is a list of dicts of data that came from a model in the database, an extra blank row is inserted after this data. I don't want a blank row to appear unless the user explicitly adds one using the JavaScript.
Is there any simple way to prevent the formset from showing an extra row if the initial data is set? The reason I'm using initial in the third example is that if I just passed the data in using MyFormset(somedata, prefix='o1-formsetname') I'd have to do an extra step of reformatting all the data into a POSTdata style dict including prefixes for each field, for example o1-formsetname-1-price: x etc., as well as calculating the management form data, which adds a whole load of complication.
One solution could be to intercept the formset before it's sent to the template and manually remove the row, but the extra_forms attribute doesn't seem to be writeable and setting extra to 0 doesn't make any difference. I could also have the JavaScript detect this case and remove the row. However I can't help but think I'm missing something obvious since the behaviour I want is what would seem to be sensible expected behaviour to me.
Thanks.
Use the max_num keyword argument to formset_factory:
MyFormset = formset_factory([...], extra=1, max_num=1)
For more details, check out limiting the maximum number of forms.
One hitch: presumably you want to be able to process more than one blank form. This isn't too hard; just make sure that you don't use the max_num keyword argument in the POST processing side.
I've come up with a solution that works with Django 1.1. I created a subclass of BaseFormSet that overrides the total_form_count method such that, if initial forms exist, the total does not include extra forms. Bit of a hack perhaps, and maybe there's a better solution that I couldn't find, but it works.
class SensibleFormset(BaseFormSet):
def total_form_count(self):
"""Returns the total number of forms in this FormSet."""
if self.data or self.files:
return self.management_form.cleaned_data[TOTAL_FORM_COUNT]
else:
if self.initial_form_count() > 0:
total_forms = self.initial_form_count()
else:
total_forms = self.initial_form_count() + self.extra
if total_forms > self.max_num > 0:
total_forms = self.max_num
return total_forms
I have a Django app that displays a list of rows in a table to the user. Each row maps to an entry in a database. I want to let the user select the rows they would like deleting by adding a checkbox to the end of each row and a delete button ( similar to how gmail lets you delete multiple mail messages). I can't quite figure out how to write the view in terms of finding out which rows were selected and how to map these to the IDs of the entries that need deleting from the database. A simple code snippet showing how to do this would be greatly appreciated.
UPDATE:
I've found this code snippet that I think should do the trick
You can use the CheckboxSelectMultiple widget to auto-generate the corresponding HTML code so you don't have to do it manually.
You can define your form like so:
class UsersForm(forms.Form):
users = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=[QuerySetIterator(Users.objects.all(), "", False)], label="")
Another advantage is that you also get validation for free.
Create a formset and pass can_delete = True to the constructor. Then, in the template,
{{formset}}