How to use helpers for list objects - python-2.7

I have this code:
my_table = db.define_table('my_table',
Field('mt_table_id', 'id', requires=[IS_NOT_EMPTY()]),
I need to add something like requires= IS_LIST() to get a list e.g. ['a','b','c'] instead of ['a,b,c']. How is that done?

I ain't got what you meant, but perhaps you should look at custom validators section in web2py's book: http://www.web2py.com/books/default/chapter/29/07/forms-and-validators#Custom-validators
You may create a custom validator called IS_LIST() and change the "formatter" method to return a list in the way that you want.

Related

Fake select field for Simple Form

I'm using Simple Form, and I have a few fields that are not associated with my model. I found using this fake field option to be a good solution:
https://github.com/plataformatec/simple_form/wiki/Create-a-fake-input-that-does-NOT-read-attributes
I thought this was cleaner than adding an attr_accessor value for my fields, and it works great for text input fields. I'm hoping to accomplish the same thing with a Select Field.
I found this thread, but I couldn't find anything else:
https://github.com/plataformatec/simple_form/issues/747
Has anyone found a similar option for a Fake Select Input? Thanks!
Assuming you'll use that "fake select" for UI purposes (probably as a mean to modify the form fields to present the user using Javascript?) and you don't want to deal with the value in the controller, you could just use select_tag with any field name, instead of the simple_form f.input. The value will be sent to the server, but it will be outside the model params, so you can just ignore it in the controller.
If I misunderstood your question, please clarify.
If your just trying to get the name='whatever' instead of having name='model[whatever]' I've found it easiest to just specify the name attribute in input_html { name: 'whatever', id: 'whatever' } hash which over rides the default model[attribute].
Otherwise you could create a fake_select_input.rb which would be similar to fake_input.rb but obviously use a select_tag instead and do something like as: :fake_select

dynamic condition for relationship(sqlalchemy) in Flask-Admin

I'm using sqlalchemy and have two models, Article and Tag, it's a many-to-many relation.
When I add articles using Flask-Admin, I want just part of tags available (related on user permission) instead of all tags.
any idea? Thanks
Probably the best way to do this is to use dynamic relationship loaders. Simply use lazy='dynamic' in your relationship definition:
posts = relationship(Post, lazy="dynamic")
This returns you a query object instead of a collection of objects, so you can then query it directly:
posts = jack.posts.filter(Post.headline=='this is a post')
You could also achieve what you want with discriminator columns or something, but that is likely overkill.
sounds like you need ModelView.get_query:
class MyView(ModelView):
def get_query(self,*args,**kwargs):
return super(MyView,self).get_query(*args,**kwargs).filter_by(current_user.can_view=True)

django how do i mix an order_by and a get in a listview url?

So i want to create:
select * from Post where Post.is_chosen = true order_by create_date
and i want this to occur in the urls.py (that is, not have to define anything, just stick it in the ListView parameters)
How do i do this?
I currently have:
url(r'^$',ListView.as_view(
queryset=Post.objects.get(is_chosen = True).order_by('-pub_date')[:20],
context_object_name='latest_post_list',
template_name='posts/index.html')),
but this has an error - i cannot call order_by on the return object of the "get" This makes sense, but how can i do what i want?
I am open to calling the command from a defined function if it is impossible to do in the url definition!
UPDATE: ARGH I am an idiot.
"get" only returns one item, so of course "order_by" won't work on it. I use filter instead now!
Like the docs say, use .filter() instead.

django orm, custom method on top of a queryset

lets suppose that some code in my view looks like this:
bar = Bar.objects.get(pk=1)
foos = bar.foo_set.filter(VERY_LONG_COMPLEX_FILTERING_LOGIC)
I would obviously want to clean the filter method a bit, by creating a custom method that does the same thing, like so:
bar = Bar.objects.get(pk=1)
foos = bar.foo_set.complexfilter()
Moving the custom method somewhere to a class would be perfect, but so far I couldn't find any mention of anything like that in the docs. Any suggestions?
Thank you in advance.
Placing it in bar's method seems good.

How can I get access to a Django Model field verbose name dynamically?

I'd like to have access to one my model field verbose_name.
I can get it by the field indice like this
model._meta._fields()[2].verbose_name
but I need to get it dynamically. Ideally it would be something like this
model._meta._fields()['location_x'].verbose_name
I've looked at a few things but I just can't find it.
For Django < 1.10:
model._meta.get_field_by_name('location_x')[0].verbose_name
model._meta.get_field('location_x').verbose_name
For Django 1.11 and 2.0:
MyModel._meta.get_field('my_field_name').verbose_name
More info in the Django doc
The selected answer gives a proxy object which might look as below.
<django.utils.functional.__proxy__ object at 0x{SomeMemoryLocation}>
If anyone is seeing the same, you can find the string for the verbose name in the title() member function of the proxy object.
model._meta.get_field_by_name(header)[0].verbose_name.title()
A better way to write this would be:
model._meta.get_field(header).verbose_name.title()
where header will be the name of the field you are interested in. i.e., 'location-x' in OPs context.
NOTE: Developers of Django also feel that using get_field is better and thus have depreciated get_field_by_name in Django 1.10. Thus I would suggest using get_field no matter what version of Django you use.
model._meta.get_field_by_name('location_x')[0].verbose_name
You can also use:
Model.location_x.field.verbose_name
Model being the class name. I tested this on my Animal model:
Animal.sale_price.field.verbose_name
Animal.sale_price returns a DeferredAttribute, which has several meta data, like the verbose_name
Note: I'm using Django 3.1.5
If you want to iterate on all the fields you need to get the field:
for f in BotUser._meta.get_fields():
if hasattr(f, 'verbose_name'):
print(f.verbose_name)
# select fields for bulk_update : exclude primary key and relational
fieldsfields_to_update = []
for field_to_update in Model._meta.get_fields():
if not field_to_update.many_to_many and not field_to_update.many_to_one and not field_to_update.one_to_many and not field_to_update.one_to_one and not field_to_update.primary_key and not field_to_update.is_relation :
fields_to_update = fields_to_update + [field_to_update.name]
Model.objects.bulk_update(models_to_update , fields_to_update)