There is a little problem with the original solution: If all categories are
already assigned to specific item, it is not possible to edit any of the
assignment.
because the drop down list is empty. This is not a problem if you do not
have any other fields (ex. comment) attached to the assignment, you can
just delete it and reasigne the same category if you wish. It is solved by
building on top of Antony's idea by including the current category in the
available categories in case of edit:
This might be a cosmetic "improvement" or a demonstration of the power of
web2py. The next challenge will be to remove the "Add new record" button
from the grid in case all categories are assigned. This can probably done
by counting the available categories and counting the assigned categories
just before showing the grid. If they are equal then there is no need to
show the add button (create =False)
def show_grid():
if 'item_category.item' in request.args:
item_id = int(request.args[request.args.index('item_category.item')
+ 1])
used_categories = db(db.item_category.item ==
item_id)._select(db.item_category.category)
if 'edit' in request.args:
item_category_id =
int(request.args[request.args.index('item_category') + 1])
current_category=db(db.item_category.id==
item_category_id)._select(db.item_category.category)
available_categories =
db(~db.category.id.belongs(used_categories) |
db.category.id.belongs(current_category))
else:
available_categories =
db(~db.category.id.belongs(used_categories))
db.item_category.category.requires = IS_IN_DB(available_categories,
'category.id', '%(name)s')
grid = SQLFORM.smartgrid(db.item)
return dict(grid=grid)
On Thursday, December 15, 2016 at 8:18:18 PM UTC+1, icodk wrote:
>
> Found explanation in :
>
> http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer?search=._select%28%29
>
> On Thursday, December 15, 2016 at 6:16:46 PM UTC+1, Anthony wrote:
>>
>> Looks like your current validator will not allow a category to be used
>> twice in the entire item_category table, which is not consistent with a
>> many-to-many relationship. Is that your intention? Or do you instead want
>> to ensure that there are no duplicate item/category *combinations* in
>> the item_category table. If the latter, you can do something like the
>> following, which will not only provide the proper validation, but will also
>> limit the list of categories in the select widget to those that have not
>> already been paired with the current item:
>>
>> def show_grid():
>> if 'item_category.item' in request.args:
>> item_id = int(request.args[request.args.index(
>> 'item_category.item') + 1])
>> used_categories = db(db.item_category.item == item_id)._select(db
>> .item_category.category)
>> available_categories = db(~db.category.id.belongs(used_categories
>> ))
>> db.item_category.category.requires = IS_IN_DB(
>> available_categories, 'category.id', '%(name)s')
>> grid = SQLFORM.smartgrid(db.item)
>> return dict(grid=grid)
>>
>> In smartgrid, when you are viewing item-categories for a given item,
>> request.args will include "item_category.item", with the immediately
>> following arg being the id of the item being viewed. So, in the above code,
>> item_id is the id of the specific item in question. use_categories is a
>> query that determines which categories have already been paired with this
>> item in the item_categories table. It uses ._select so it can be passed
>> to .belongs as a subquery. available_categories is a Set object that
>> identifies categories that have *not* been paired with the current item
>> in item_categories. When you pass a Set object to IS_IN_DB, it restricts
>> values to records that are in the Set, so the validator will only allow
>> (and display in the form) categories not already assigned to the item.
>>
>> Anthony
>>
>> On Wednesday, December 14, 2016 at 5:31:11 PM UTC-5, icodk wrote:
>>>
>>> I have an item ,category and item_category tables facilitating many to
>>> many relations between items and categories, which enables an item to
>>> belongs to several categories. I use SQLSmartgrid to show the
>>> item_category table and to add categories to specific item. This all works
>>> well. I can even managed to get an error if I select an already selected
>>> category by using the following:
>>>
>>> db.item_category.category.requires = IS_IN_DB(db, 'category', '%(name)s',
>>> _and=IS_NOT_IN_DB(db, 'item_category.category', error_message=T('This
>>> category already assigned')), zero=None)
>>>
>>>
>>> So what more could I wish ?
>>>
>>> It would be nice if the category dropdown list I get when adding or editing
>>> category to an item would contains only the categories not yet assigned to
>>> the item I am working on
>>>
>>> At the moment I get a list with all categories, however selecting an
>>> existing category correctly give me an error as described above.
>>>
>>>
>>>
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.