1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198 |
- from nose.tools import eq_, ok_
- from wtforms import fields, validators
- from flask_admin import form
- from flask_admin._compat import as_unicode
- from flask_admin.contrib.mongoengine import ModelView
- from . import setup
- from datetime import datetime
- class CustomModelView(ModelView):
- def __init__(self, model,
- name=None, category=None, endpoint=None, url=None,
- **kwargs):
- for k, v in kwargs.iteritems():
- setattr(self, k, v)
- super(CustomModelView, self).__init__(model,
- name, category,
- endpoint, url)
- def create_models(db):
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- test2 = db.StringField(max_length=20)
- test3 = db.StringField()
- test4 = db.StringField()
- datetime_field = db.DateTimeField()
- def __str__(self):
- return self.test1
- class Model2(db.Document):
- string_field = db.StringField()
- int_field = db.IntField()
- float_field = db.FloatField()
- bool_field = db.BooleanField()
- model1 = db.ReferenceField(Model1)
- Model1.objects.delete()
- Model2.objects.delete()
- return Model1, Model2
- def fill_db(Model1, Model2):
- Model1('test1_val_1', 'test2_val_1').save()
- Model1('test1_val_2', 'test2_val_2').save()
- Model1('test1_val_3', 'test2_val_3').save()
- Model1('test1_val_4', 'test2_val_4').save()
- Model1(None, 'empty_obj').save()
- Model2('string_field_val_1', None, None, True).save()
- Model2('string_field_val_2', None, None, False).save()
- Model2('string_field_val_3', 5000, 25.9).save()
- Model2('string_field_val_4', 9000, 75.5).save()
- Model2('string_field_val_5', 6169453081680413441).save()
- Model1('datetime_obj1', datetime_field=datetime(2014, 4, 3, 1, 9, 0)).save()
- Model1('datetime_obj2', datetime_field=datetime(2013, 3, 2, 0, 8, 0)).save()
- def test_model():
- app, db, admin = setup()
- Model1, Model2 = create_models(db)
- view = CustomModelView(Model1)
- admin.add_view(view)
- eq_(view.model, Model1)
- eq_(view.name, 'Model1')
- eq_(view.endpoint, 'model1')
- eq_(view._primary_key, 'id')
- ok_('test1' in view._sortable_columns)
- ok_('test2' in view._sortable_columns)
- ok_('test3' in view._sortable_columns)
- ok_('test4' in view._sortable_columns)
- ok_(view._create_form_class is not None)
- ok_(view._edit_form_class is not None)
- eq_(view._search_supported, False)
- eq_(view._filters, None)
- eq_(view._create_form_class.test1.field_class, fields.StringField)
- eq_(view._create_form_class.test2.field_class, fields.StringField)
- eq_(view._create_form_class.test3.field_class, fields.TextAreaField)
- eq_(view._create_form_class.test4.field_class, fields.TextAreaField)
- # Make some test clients
- client = app.test_client()
- rv = client.get('/admin/model1/')
- eq_(rv.status_code, 200)
- rv = client.get('/admin/model1/new/')
- eq_(rv.status_code, 200)
- rv = client.post('/admin/model1/new/',
- data=dict(test1='test1large', test2='test2'))
- eq_(rv.status_code, 302)
- model = Model1.objects.first()
- eq_(model.test1, 'test1large')
- eq_(model.test2, 'test2')
- eq_(model.test3, '')
- eq_(model.test4, '')
- rv = client.get('/admin/model1/')
- eq_(rv.status_code, 200)
- ok_('test1large' in rv.data)
- url = '/admin/model1/edit/?id=%s' % model.id
- rv = client.get(url)
- eq_(rv.status_code, 200)
- rv = client.post(url,
- data=dict(test1='test1small', test2='test2large'))
- eq_(rv.status_code, 302)
- model = Model1.objects.first()
- eq_(model.test1, 'test1small')
- eq_(model.test2, 'test2large')
- eq_(model.test3, '')
- eq_(model.test4, '')
- url = '/admin/model1/delete/?id=%s' % model.id
- rv = client.post(url)
- eq_(rv.status_code, 302)
- eq_(Model1.objects.count(), 0)
- def test_column_editable_list():
- app, db, admin = setup()
- Model1, Model2 = create_models(db)
- view = CustomModelView(Model1,
- column_editable_list=['test1', 'datetime_field'])
- admin.add_view(view)
- fill_db(Model1, Model2)
- client = app.test_client()
- # Test in-line edit field rendering
- rv = client.get('/admin/model1/')
- data = rv.data.decode('utf-8')
- ok_('data-role="x-editable"' in data)
- # Form - Test basic in-line edit functionality
- obj1 = Model1.objects.get(test1='test1_val_3')
- rv = client.post('/admin/model1/ajax/update/', data={
- 'list_form_pk': str(obj1.id),
- 'test1': 'change-success-1',
- })
- data = rv.data.decode('utf-8')
- ok_('Record was successfully saved.' == data)
- # confirm the value has changed
- rv = client.get('/admin/model1/')
- data = rv.data.decode('utf-8')
- ok_('change-success-1' in data)
- # Test validation error
- obj2 = Model1.objects.get(test1='datetime_obj1')
- rv = client.post('/admin/model1/ajax/update/', data={
- 'list_form_pk': str(obj2.id),
- 'datetime_field': 'problematic-input',
- })
- eq_(rv.status_code, 500)
- # Test invalid primary key
- rv = client.post('/admin/model1/ajax/update/', data={
- 'list_form_pk': '1000',
- 'test1': 'problematic-input',
- })
- data = rv.data.decode('utf-8')
- eq_(rv.status_code, 500)
- # Test editing column not in column_editable_list
- rv = client.post('/admin/model1/ajax/update/', data={
- 'list_form_pk': '1',
- 'test2': 'problematic-input',
- })
- data = rv.data.decode('utf-8')
- ok_('problematic-input' not in data)
- # Test in-line editing for relations
- view = CustomModelView(Model2, column_editable_list=['model1'])
- admin.add_view(view)
- obj3 = Model2.objects.get(string_field='string_field_val_1')
- rv = client.post('/admin/model2/ajax/update/', data={
- 'list_form_pk': str(obj3.id),
- 'model1': str(obj1.id),
- })
- data = rv.data.decode('utf-8')
- ok_('Record was successfully saved.' == data)
- # confirm the value has changed
- rv = client.get('/admin/model2/')
- data = rv.data.decode('utf-8')
- ok_('test1_val_1' in data)
- def test_details_view():
- app, db, admin = setup()
- Model1, Model2 = create_models(db)
- view_no_details = CustomModelView(Model1)
- admin.add_view(view_no_details)
- # fields are scaffolded
- view_w_details = CustomModelView(Model2, can_view_details=True)
- admin.add_view(view_w_details)
- # show only specific fields in details w/ column_details_list
- string_field_view = CustomModelView(Model2, can_view_details=True,
- column_details_list=["string_field"],
- endpoint="sf_view")
- admin.add_view(string_field_view)
- fill_db(Model1, Model2)
- client = app.test_client()
- m1_id = Model1.objects.first().id
- m2_id = Model2.objects.first().id
- # ensure link to details is hidden when can_view_details is disabled
- rv = client.get('/admin/model1/')
- data = rv.data.decode('utf-8')
- ok_('/admin/model1/details/' not in data)
- # ensure link to details view appears
- rv = client.get('/admin/model2/')
- data = rv.data.decode('utf-8')
- ok_('/admin/model2/details/' in data)
- # test redirection when details are disabled
- url = '/admin/model1/details/?url=%2Fadmin%2Fmodel1%2F&id=' + str(m1_id)
- rv = client.get(url)
- eq_(rv.status_code, 302)
- # test if correct data appears in details view when enabled
- url = '/admin/model2/details/?url=%2Fadmin%2Fmodel2%2F&id=' + str(m2_id)
- rv = client.get(url)
- data = rv.data.decode('utf-8')
- ok_('String Field' in data)
- ok_('string_field_val_1' in data)
- ok_('Int Field' in data)
- # test column_details_list
- url = '/admin/sf_view/details/?url=%2Fadmin%2Fsf_view%2F&id=' + str(m2_id)
- rv = client.get(url)
- data = rv.data.decode('utf-8')
- ok_('String Field' in data)
- ok_('string_field_val_1' in data)
- ok_('Int Field' not in data)
- def test_column_filters():
- app, db, admin = setup()
- Model1, Model2 = create_models(db)
- # fill DB with values
- fill_db(Model1, Model2)
- # Test string filter
- view = CustomModelView(Model1, column_filters=['test1'])
- admin.add_view(view)
- eq_(len(view._filters), 7)
- eq_(
- [(f['index'], f['operation']) for f in view._filter_groups[u'Test1']],
- [
- (0, 'contains'),
- (1, 'not contains'),
- (2, 'equals'),
- (3, 'not equal'),
- (4, 'empty'),
- (5, 'in list'),
- (6, 'not in list'),
- ]
- )
- # Make some test clients
- client = app.test_client()
- # string - equals
- rv = client.get('/admin/model1/?flt0_0=test1_val_1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('test2_val_1' in data)
- ok_('test1_val_2' not in data)
- # string - not equal
- rv = client.get('/admin/model1/?flt0_1=test1_val_1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('test2_val_1' not in data)
- ok_('test1_val_2' in data)
- # string - contains
- rv = client.get('/admin/model1/?flt0_2=test1_val_1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('test2_val_1' in data)
- ok_('test1_val_2' not in data)
- # string - not contains
- rv = client.get('/admin/model1/?flt0_3=test1_val_1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('test2_val_1' not in data)
- ok_('test1_val_2' in data)
- # string - empty
- rv = client.get('/admin/model1/?flt0_4=1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('empty_obj' in data)
- ok_('test1_val_1' not in data)
- ok_('test1_val_2' not in data)
- # string - not empty
- rv = client.get('/admin/model1/?flt0_4=0')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('empty_obj' not in data)
- ok_('test1_val_1' in data)
- ok_('test1_val_2' in data)
- # string - in list
- rv = client.get('/admin/model1/?flt0_5=test1_val_1%2Ctest1_val_2')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('test2_val_1' in data)
- ok_('test2_val_2' in data)
- ok_('test1_val_3' not in data)
- ok_('test1_val_4' not in data)
- # string - not in list
- rv = client.get('/admin/model1/?flt0_6=test1_val_1%2Ctest1_val_2')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('test2_val_1' not in data)
- ok_('test2_val_2' not in data)
- ok_('test1_val_3' in data)
- ok_('test1_val_4' in data)
- # Test numeric filter
- view = CustomModelView(Model2, column_filters=['int_field'])
- admin.add_view(view)
- eq_(
- [(f['index'], f['operation']) for f in view._filter_groups[u'Int Field']],
- [
- (0, 'equals'),
- (1, 'not equal'),
- (2, 'greater than'),
- (3, 'smaller than'),
- (4, 'empty'),
- (5, 'in list'),
- (6, 'not in list'),
- ]
- )
- # integer - equals
- rv = client.get('/admin/model2/?flt0_0=5000')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_3' in data)
- ok_('string_field_val_4' not in data)
- # integer - equals (huge number)
- rv = client.get('/admin/model2/?flt0_0=6169453081680413441')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_5' in data)
- ok_('string_field_val_4' not in data)
- # integer - equals - test validation
- rv = client.get('/admin/model2/?flt0_0=badval')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('Invalid Filter Value' in data)
- # integer - not equal
- rv = client.get('/admin/model2/?flt0_1=5000')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_3' not in data)
- ok_('string_field_val_4' in data)
- # integer - greater
- rv = client.get('/admin/model2/?flt0_2=6000')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_3' not in data)
- ok_('string_field_val_4' in data)
- # integer - smaller
- rv = client.get('/admin/model2/?flt0_3=6000')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_3' in data)
- ok_('string_field_val_4' not in data)
- # integer - empty
- rv = client.get('/admin/model2/?flt0_4=1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' in data)
- ok_('string_field_val_2' in data)
- ok_('string_field_val_3' not in data)
- ok_('string_field_val_4' not in data)
- # integer - not empty
- rv = client.get('/admin/model2/?flt0_4=0')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' not in data)
- ok_('string_field_val_2' not in data)
- ok_('string_field_val_3' in data)
- ok_('string_field_val_4' in data)
- # integer - in list
- rv = client.get('/admin/model2/?flt0_5=5000%2C9000')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' not in data)
- ok_('string_field_val_2' not in data)
- ok_('string_field_val_3' in data)
- ok_('string_field_val_4' in data)
- # integer - in list (huge number)
- rv = client.get('/admin/model2/?flt0_5=6169453081680413441')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' not in data)
- ok_('string_field_val_5' in data)
- # integer - in list - test validation
- rv = client.get('/admin/model2/?flt0_5=5000%2Cbadval')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('Invalid Filter Value' in data)
- # integer - not in list
- rv = client.get('/admin/model2/?flt0_6=5000%2C9000')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' in data)
- ok_('string_field_val_2' in data)
- ok_('string_field_val_3' not in data)
- ok_('string_field_val_4' not in data)
- # Test boolean filter
- view = CustomModelView(Model2, column_filters=['bool_field'],
- endpoint="_bools")
- admin.add_view(view)
- eq_(
- [(f['index'], f['operation']) for f in view._filter_groups[u'Bool Field']],
- [
- (0, 'equals'),
- (1, 'not equal'),
- ]
- )
- # boolean - equals - Yes
- rv = client.get('/admin/_bools/?flt0_0=1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' in data)
- ok_('string_field_val_2' not in data)
- # boolean - equals - No
- rv = client.get('/admin/_bools/?flt0_0=0')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' not in data)
- ok_('string_field_val_2' in data)
- # boolean - not equals - Yes
- rv = client.get('/admin/_bools/?flt0_1=1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' not in data)
- ok_('string_field_val_2' in data)
- # boolean - not equals - No
- rv = client.get('/admin/_bools/?flt0_1=0')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' in data)
- ok_('string_field_val_2' not in data)
- # Test float filter
- view = CustomModelView(Model2, column_filters=['float_field'],
- endpoint="_float")
- admin.add_view(view)
- eq_(
- [(f['index'], f['operation']) for f in view._filter_groups[u'Float Field']],
- [
- (0, 'equals'),
- (1, 'not equal'),
- (2, 'greater than'),
- (3, 'smaller than'),
- (4, 'empty'),
- (5, 'in list'),
- (6, 'not in list'),
- ]
- )
- # float - equals
- rv = client.get('/admin/_float/?flt0_0=25.9')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_3' in data)
- ok_('string_field_val_4' not in data)
- # float - equals - test validation
- rv = client.get('/admin/_float/?flt0_0=badval')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('Invalid Filter Value' in data)
- # float - not equal
- rv = client.get('/admin/_float/?flt0_1=25.9')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_3' not in data)
- ok_('string_field_val_4' in data)
- # float - greater
- rv = client.get('/admin/_float/?flt0_2=60.5')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_3' not in data)
- ok_('string_field_val_4' in data)
- # float - smaller
- rv = client.get('/admin/_float/?flt0_3=60.5')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_3' in data)
- ok_('string_field_val_4' not in data)
- # float - empty
- rv = client.get('/admin/_float/?flt0_4=1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' in data)
- ok_('string_field_val_2' in data)
- ok_('string_field_val_3' not in data)
- ok_('string_field_val_4' not in data)
- # float - not empty
- rv = client.get('/admin/_float/?flt0_4=0')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' not in data)
- ok_('string_field_val_2' not in data)
- ok_('string_field_val_3' in data)
- ok_('string_field_val_4' in data)
- # float - in list
- rv = client.get('/admin/_float/?flt0_5=25.9%2C75.5')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' not in data)
- ok_('string_field_val_2' not in data)
- ok_('string_field_val_3' in data)
- ok_('string_field_val_4' in data)
- # float - in list - test validation
- rv = client.get('/admin/_float/?flt0_5=25.9%2Cbadval')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('Invalid Filter Value' in data)
- # float - not in list
- rv = client.get('/admin/_float/?flt0_6=25.9%2C75.5')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('string_field_val_1' in data)
- ok_('string_field_val_2' in data)
- ok_('string_field_val_3' not in data)
- ok_('string_field_val_4' not in data)
- # Test datetime filter
- view = CustomModelView(Model1,
- column_filters=['datetime_field'],
- endpoint="_datetime")
- admin.add_view(view)
- eq_(
- [(f['index'], f['operation']) for f in view._filter_groups[u'Datetime Field']],
- [
- (0, 'equals'),
- (1, 'not equal'),
- (2, 'greater than'),
- (3, 'smaller than'),
- (4, 'between'),
- (5, 'not between'),
- (6, 'empty'),
- ]
- )
- # datetime - equals
- rv = client.get('/admin/_datetime/?flt0_0=2014-04-03+01%3A09%3A00')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('datetime_obj1' in data)
- ok_('datetime_obj2' not in data)
- # datetime - not equal
- rv = client.get('/admin/_datetime/?flt0_1=2014-04-03+01%3A09%3A00')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('datetime_obj1' not in data)
- ok_('datetime_obj2' in data)
- # datetime - greater
- rv = client.get('/admin/_datetime/?flt0_2=2014-04-03+01%3A08%3A00')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('datetime_obj1' in data)
- ok_('datetime_obj2' not in data)
- # datetime - smaller
- rv = client.get('/admin/_datetime/?flt0_3=2014-04-03+01%3A08%3A00')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('datetime_obj1' not in data)
- ok_('datetime_obj2' in data)
- # datetime - between
- rv = client.get('/admin/_datetime/?flt0_4=2014-04-02+00%3A00%3A00+to+2014-11-20+23%3A59%3A59')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('datetime_obj1' in data)
- ok_('datetime_obj2' not in data)
- # datetime - not between
- rv = client.get('/admin/_datetime/?flt0_5=2014-04-02+00%3A00%3A00+to+2014-11-20+23%3A59%3A59')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('datetime_obj1' not in data)
- ok_('datetime_obj2' in data)
- # datetime - empty
- rv = client.get('/admin/_datetime/?flt0_6=1')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('test1_val_1' in data)
- ok_('datetime_obj1' not in data)
- ok_('datetime_obj2' not in data)
- # datetime - not empty
- rv = client.get('/admin/_datetime/?flt0_6=0')
- eq_(rv.status_code, 200)
- data = rv.data.decode('utf-8')
- ok_('test1_val_1' not in data)
- ok_('datetime_obj1' in data)
- ok_('datetime_obj2' in data)
- def test_default_sort():
- app, db, admin = setup()
- M1, _ = create_models(db)
- M1(test1='c').save()
- M1(test1='b').save()
- M1(test1='a').save()
- eq_(M1.objects.count(), 3)
- view = CustomModelView(M1, column_default_sort='test1')
- admin.add_view(view)
- _, data = view.get_list(0, None, None, None, None)
- eq_(data[0].test1, 'a')
- eq_(data[1].test1, 'b')
- eq_(data[2].test1, 'c')
- def test_extra_fields():
- app, db, admin = setup()
- Model1, _ = create_models(db)
- view = CustomModelView(
- Model1,
- form_extra_fields={
- 'extra_field': fields.StringField('Extra Field')
- }
- )
- admin.add_view(view)
- client = app.test_client()
- rv = client.get('/admin/model1/new/')
- eq_(rv.status_code, 200)
- # Check presence and order
- data = rv.data.decode('utf-8')
- ok_('Extra Field' in data)
- pos1 = data.find('Extra Field')
- pos2 = data.find('Test1')
- ok_(pos2 < pos1)
- def test_extra_field_order():
- app, db, admin = setup()
- Model1, _ = create_models(db)
- view = CustomModelView(
- Model1,
- form_extra_fields={
- 'extra_field': fields.StringField('Extra Field')
- }
- )
- admin.add_view(view)
- client = app.test_client()
- rv = client.get('/admin/model1/new/')
- eq_(rv.status_code, 200)
- # Check presence and order
- data = rv.data.decode('utf-8')
- ok_('Extra Field' in data)
- pos1 = data.find('Extra Field')
- pos2 = data.find('Test1')
- ok_(pos2 < pos1)
- def test_custom_form_base():
- app, db, admin = setup()
- class TestForm(form.BaseForm):
- pass
- Model1, _ = create_models(db)
- view = CustomModelView(
- Model1,
- form_base_class=TestForm
- )
- admin.add_view(view)
- ok_(hasattr(view._create_form_class, 'test1'))
- create_form = view.create_form()
- ok_(isinstance(create_form, TestForm))
- def test_subdocument_config():
- app, db, admin = setup()
- class Comment(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- value = db.StringField(max_length=20)
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- subdoc = db.EmbeddedDocumentField(Comment)
- # Check only
- view1 = CustomModelView(
- Model1,
- form_subdocuments={
- 'subdoc': {
- 'form_columns': ('name',)
- }
- }
- )
- ok_(hasattr(view1._create_form_class, 'subdoc'))
- form = view1.create_form()
- ok_('name' in dir(form.subdoc.form))
- ok_('value' not in dir(form.subdoc.form))
- # Check exclude
- view2 = CustomModelView(
- Model1,
- form_subdocuments={
- 'subdoc': {
- 'form_excluded_columns': ('value',)
- }
- }
- )
- form = view2.create_form()
- ok_('name' in dir(form.subdoc.form))
- ok_('value' not in dir(form.subdoc.form))
- def test_subdocument_class_config():
- app, db, admin = setup()
- from flask_admin.contrib.mongoengine import EmbeddedForm
- class Comment(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- value = db.StringField(max_length=20)
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- subdoc = db.EmbeddedDocumentField(Comment)
- class EmbeddedConfig(EmbeddedForm):
- form_columns = ('name',)
- # Check only
- view1 = CustomModelView(
- Model1,
- form_subdocuments={
- 'subdoc': EmbeddedConfig()
- }
- )
- form = view1.create_form()
- ok_('name' in dir(form.subdoc.form))
- ok_('value' not in dir(form.subdoc.form))
- def test_nested_subdocument_config():
- app, db, admin = setup()
- # Check recursive
- class Comment(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- value = db.StringField(max_length=20)
- class Nested(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- comment = db.EmbeddedDocumentField(Comment)
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- nested = db.EmbeddedDocumentField(Nested)
- view1 = CustomModelView(
- Model1,
- form_subdocuments={
- 'nested': {
- 'form_subdocuments': {
- 'comment': {
- 'form_columns': ('name',)
- }
- }
- }
- }
- )
- form = view1.create_form()
- ok_('name' in dir(form.nested.form.comment.form))
- ok_('value' not in dir(form.nested.form.comment.form))
- def test_nested_list_subdocument():
- app, db, admin = setup()
- class Comment(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- value = db.StringField(max_length=20)
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- subdoc = db.ListField(db.EmbeddedDocumentField(Comment))
- # Check only
- view1 = CustomModelView(
- Model1,
- form_subdocuments={
- 'subdoc': {
- 'form_subdocuments': {
- None: {
- 'form_columns': ('name',)
- }
- }
- }
- }
- )
- form = view1.create_form()
- inline_form = form.subdoc.unbound_field.args[2]
- ok_('name' in dir(inline_form))
- ok_('value' not in dir(inline_form))
- def test_nested_sortedlist_subdocument():
- app, db, admin = setup()
- class Comment(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- value = db.StringField(max_length=20)
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- subdoc = db.SortedListField(db.EmbeddedDocumentField(Comment))
- # Check only
- view1 = CustomModelView(
- Model1,
- form_subdocuments={
- 'subdoc': {
- 'form_subdocuments': {
- None: {
- 'form_columns': ('name',)
- }
- }
- }
- }
- )
- form = view1.create_form()
- inline_form = form.subdoc.unbound_field.args[2]
- ok_('name' in dir(inline_form))
- ok_('value' not in dir(inline_form))
- def test_sortedlist_subdocument_validation():
- app, db, admin = setup()
- class Comment(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- value = db.StringField(max_length=20)
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- subdoc = db.SortedListField(db.EmbeddedDocumentField(Comment))
- view = CustomModelView(Model1)
- admin.add_view(view)
- client = app.test_client()
- rv = client.post('/admin/model1/new/',
- data={'test1': 'test1large', 'subdoc-0-name': 'comment', 'subdoc-0-value': 'test'})
- eq_(rv.status_code, 302)
- rv = client.post('/admin/model1/new/',
- data={'test1': 'test1large', 'subdoc-0-name': '', 'subdoc-0-value': 'test'})
- eq_(rv.status_code, 200)
- ok_('This field is required' in rv.data)
- def test_list_subdocument_validation():
- app, db, admin = setup()
- class Comment(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- value = db.StringField(max_length=20)
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- subdoc = db.ListField(db.EmbeddedDocumentField(Comment))
- view = CustomModelView(Model1)
- admin.add_view(view)
- client = app.test_client()
- rv = client.post('/admin/model1/new/',
- data={'test1': 'test1large', 'subdoc-0-name': 'comment', 'subdoc-0-value': 'test'})
- eq_(rv.status_code, 302)
- rv = client.post('/admin/model1/new/',
- data={'test1': 'test1large', 'subdoc-0-name': '', 'subdoc-0-value': 'test'})
- eq_(rv.status_code, 200)
- ok_('This field is required' in rv.data)
- def test_ajax_fk():
- app, db, admin = setup()
- Model1, Model2 = create_models(db)
- view = CustomModelView(
- Model2,
- url='view',
- form_ajax_refs={
- 'model1': {
- 'fields': ('test1', 'test2')
- }
- }
- )
- admin.add_view(view)
- ok_(u'model1' in view._form_ajax_refs)
- model = Model1(test1=u'first')
- model.save()
- model2 = Model1(test1=u'foo', test2=u'bar').save()
- # Check loader
- loader = view._form_ajax_refs[u'model1']
- mdl = loader.get_one(model.id)
- eq_(mdl.test1, model.test1)
- items = loader.get_list(u'fir')
- eq_(len(items), 1)
- eq_(items[0].id, model.id)
- items = loader.get_list(u'bar')
- eq_(len(items), 1)
- eq_(items[0].test1, u'foo')
- # Check form generation
- form = view.create_form()
- eq_(form.model1.__class__.__name__, u'AjaxSelectField')
- with app.test_request_context('/admin/view/'):
- ok_(u'value=""' not in form.model1())
- form.model1.data = model
- needle = u'data-json="["%s", "first"]"' % as_unicode(model.id)
- ok_(needle in form.model1())
- ok_(u'value="%s"' % as_unicode(model.id) in form.model1())
- # Check querying
- client = app.test_client()
- req = client.get(u'/admin/view/ajax/lookup/?name=model1&query=foo')
- eq_(req.data, u'[["%s", "foo"]]' % model2.id)
- # Check submitting
- client.post('/admin/view/new/', data={u'model1': as_unicode(model.id)})
- mdl = Model2.objects.first()
- ok_(mdl is not None)
- ok_(mdl.model1 is not None)
- eq_(mdl.model1.id, model.id)
- eq_(mdl.model1.test1, u'first')
- def test_nested_ajax_refs():
- app, db, admin = setup()
- # Check recursive
- class Comment(db.Document):
- name = db.StringField(max_length=20, required=True)
- value = db.StringField(max_length=20)
- class Nested(db.EmbeddedDocument):
- name = db.StringField(max_length=20, required=True)
- comment = db.ReferenceField(Comment)
- class Model1(db.Document):
- test1 = db.StringField(max_length=20)
- nested = db.EmbeddedDocumentField(Nested)
- view1 = CustomModelView(
- Model1,
- form_subdocuments={
- 'nested': {
- 'form_ajax_refs': {
- 'comment': {
- 'fields': ['name']
- }
- }
- }
- }
- )
- form = view1.create_form()
- eq_(type(form.nested.form.comment).__name__, 'AjaxSelectField')
- ok_('nested-comment' in view1._form_ajax_refs)
- def test_form_flat_choices():
- app, db, admin = setup()
- class Model(db.Document):
- name = db.StringField(max_length=20, choices=('a', 'b', 'c'))
- view = CustomModelView(Model)
- admin.add_view(view)
- form = view.create_form()
- eq_(form.name.choices, [('a', 'a'), ('b', 'b'), ('c', 'c')])
- def test_form_args():
- app, db, admin = setup()
- class Model(db.Document):
- test = db.StringField(required=True)
- shared_form_args = {'test': {'validators': [validators.Regexp('test')]}}
- view = CustomModelView(Model, form_args=shared_form_args)
- admin.add_view(view)
- # ensure shared field_args don't create duplicate validators
- create_form = view.create_form()
- eq_(len(create_form.test.validators), 2)
- edit_form = view.edit_form()
- eq_(len(edit_form.test.validators), 2)
- def test_form_args_embeddeddoc():
- app, db, admin = setup()
- class Info(db.EmbeddedDocument):
- name = db.StringField()
- age = db.StringField()
- class Model(db.Document):
- info = db.EmbeddedDocumentField('Info')
- timestamp = db.DateTimeField()
- view = CustomModelView(
- Model,
- form_args={
- 'info': {'label': 'Information'},
- 'timestamp': {'label': 'Last Updated Time'}
- }
- )
- admin.add_view(view)
- form = view.create_form()
- eq_(form.timestamp.label.text, 'Last Updated Time')
- # This is the failure
- eq_(form.info.label.text, 'Information')
- def test_simple_list_pager():
- app, db, admin = setup()
- Model1, _ = create_models(db)
- class TestModelView(CustomModelView):
- simple_list_pager = True
- def get_count_query(self):
- assert False
- view = TestModelView(Model1)
- admin.add_view(view)
- count, data = view.get_list(0, None, None, None, None)
- ok_(count is None)
- def test_export_csv():
- app, db, admin = setup()
- Model1, Model2 = create_models(db)
- view = CustomModelView(Model1, can_export=True,
- column_list=['test1', 'test2'], export_max_rows=2,
- endpoint='row_limit_2')
- admin.add_view(view)
- for x in range(5):
- fill_db(Model1, Model2)
- client = app.test_client()
- # test export_max_rows
- rv = client.get('/admin/row_limit_2/export/csv/')
- data = rv.data.decode('utf-8')
- eq_(rv.status_code, 200)
- ok_("Test1,Test2\r\n"
- "test1_val_1,test2_val_1\r\n"
- "test1_val_2,test2_val_2\r\n" == data)
- view = CustomModelView(Model1, can_export=True,
- column_list=['test1', 'test2'],
- endpoint='no_row_limit')
- admin.add_view(view)
- # test row limit without export_max_rows
- rv = client.get('/admin/no_row_limit/export/csv/')
- data = rv.data.decode('utf-8')
- eq_(rv.status_code, 200)
- ok_(len(data.splitlines()) > 21)
|