0001-datasources-refuse-to-delete-or-change-slug-of-datas.patch
tests/test_admin_pages.py | ||
---|---|---|
4855 | 4855 |
resp = resp.follow() |
4856 | 4856 |
assert NamedDataSource.count() == 0 |
4857 | 4857 | |
4858 |
def test_data_sources_in_use_delete(pub): |
|
4859 |
create_superuser(pub) |
|
4860 |
NamedDataSource.wipe() |
|
4861 |
category = NamedDataSource(name='foobar') |
|
4862 |
category.store() |
|
4863 | ||
4864 |
FormDef.wipe() |
|
4865 |
formdef = FormDef() |
|
4866 |
formdef.name = 'form title' |
|
4867 |
formdef.fields = [ |
|
4868 |
fields.ItemField(id='0', label='string', type='item', |
|
4869 |
data_source={'type': 'foobar'}), |
|
4870 |
] |
|
4871 |
formdef.store() |
|
4872 | ||
4873 |
app = login(get_app(pub)) |
|
4874 |
resp = app.get('/backoffice/settings/data-sources/1/') |
|
4875 |
resp = app.get('/backoffice/settings/data-sources/1/delete', status=404) |
|
4876 | ||
4858 | 4877 |
def test_data_sources_edit_slug(pub): |
4859 | 4878 |
create_superuser(pub) |
4860 | 4879 |
NamedDataSource.wipe() |
... | ... | |
4889 | 4908 |
resp = resp.forms[0].submit('submit') |
4890 | 4909 |
assert resp.location == 'http://example.net/backoffice/settings/data-sources/1/' |
4891 | 4910 | |
4911 |
def test_data_sources_in_use_edit_slug(pub): |
|
4912 |
create_superuser(pub) |
|
4913 |
NamedDataSource.wipe() |
|
4914 |
data_source = NamedDataSource(name='foobar') |
|
4915 |
data_source.data_source = {'type': 'formula', 'value': '[]'} |
|
4916 |
data_source.store() |
|
4917 | ||
4918 |
FormDef.wipe() |
|
4919 |
formdef = FormDef() |
|
4920 |
app = login(get_app(pub)) |
|
4921 |
resp = app.get('/backoffice/settings/data-sources/1/') |
|
4922 |
resp = resp.click(href='edit') |
|
4923 | ||
4924 |
formdef.name = 'form title' |
|
4925 |
formdef.fields = [ |
|
4926 |
fields.ItemField(id='0', label='string', type='item', |
|
4927 |
data_source={'type': 'foobar'}), |
|
4928 |
] |
|
4929 |
formdef.store() |
|
4930 | ||
4931 |
assert NamedDataSource.get(1).slug == 'foobar' |
|
4932 |
resp.forms[0]['slug'] = 'barfoo' |
|
4933 |
resp = resp.forms[0].submit('submit', status=404) |
|
4934 | ||
4892 | 4935 |
def test_wscalls_new(pub): |
4893 | 4936 |
create_superuser(pub) |
4894 | 4937 |
NamedWsCall.wipe() |
wcs/admin/data_sources.py | ||
---|---|---|
20 | 20 | |
21 | 21 |
from ..qommon import _ |
22 | 22 |
from ..qommon import template |
23 |
from ..qommon import errors |
|
23 | 24 |
from ..qommon.form import * |
24 | 25 |
from ..qommon.misc import json_response |
25 | 26 |
from ..qommon.backoffice.menu import html_top |
26 | 27 |
from wcs.data_sources import (NamedDataSource, DataSourceSelectionWidget, |
27 | 28 |
get_structured_items) |
28 |
from wcs.formdef import FormDef |
|
29 |
from wcs.formdef import FormDef, get_formdefs_of_all_kinds
|
|
29 | 30 | |
30 | 31 |
class NamedDataSourceUI(object): |
31 | 32 |
def __init__(self, datasource): |
... | ... | |
33 | 34 |
if self.datasource is None: |
34 | 35 |
self.datasource = NamedDataSource() |
35 | 36 | |
37 |
def is_datasource_in_use(self): |
|
38 |
for formdef in get_formdefs_of_all_kinds(): |
|
39 |
if formdef.is_using_datasource(self.datasource): |
|
40 |
return True |
|
41 |
return False |
|
42 | ||
36 | 43 |
def get_form(self): |
37 | 44 |
form = Form(enctype='multipart/form-data', |
38 | 45 |
advanced_label=_('Additional options')) |
... | ... | |
95 | 102 |
slug = form.get_widget('slug').parse() |
96 | 103 |
else: |
97 | 104 |
slug = None |
105 |
if self.datasource.slug != slug and self.is_datasource_in_use(): |
|
106 |
raise errors.TraversalError() |
|
98 | 107 | |
99 | 108 |
for nds in NamedDataSource.select(): |
100 | 109 |
if nds.id == self.datasource.id: |
... | ... | |
135 | 144 |
def usage_in_formdefs(self): |
136 | 145 |
formdefs = [] |
137 | 146 |
for formdef in FormDef.select(ignore_errors=True, ignore_migration=True, order_by='name'): |
138 |
for field in (formdef.fields or []): |
|
139 |
data_source = getattr(field, 'data_source', None) |
|
140 |
if not data_source: |
|
141 |
continue |
|
142 |
if data_source.get('type') == self.datasource.slug: |
|
143 |
formdefs.append(formdef) |
|
144 |
break |
|
145 |
else: |
|
146 |
continue |
|
147 |
if formdef.is_using_datasource(self.datasource): |
|
148 |
formdefs.append(formdef) |
|
147 | 149 |
return formdefs |
148 | 150 | |
149 | 151 |
def preview_block(self): |
... | ... | |
198 | 200 |
return r.getvalue() |
199 | 201 | |
200 | 202 |
def delete(self): |
203 |
if self.datasource_ui.is_datasource_in_use(): |
|
204 |
raise errors.TraversalError() |
|
201 | 205 |
form = Form(enctype='multipart/form-data') |
202 | 206 |
form.widgets.append(HtmlWidget('<p>%s</p>' % _( |
203 | 207 |
'You are about to irrevocably delete this data source.'))) |
wcs/formdef.py | ||
---|---|---|
1414 | 1414 |
if changed: |
1415 | 1415 |
formdef.store() |
1416 | 1416 | |
1417 |
def is_using_datasource(self, datasource): |
|
1418 |
for field in (self.fields or []): |
|
1419 |
data_source = getattr(field, 'data_source', None) |
|
1420 |
if not data_source: |
|
1421 |
continue |
|
1422 |
if data_source.get('type') == datasource.slug: |
|
1423 |
return True |
|
1424 |
return False |
|
1425 | ||
1417 | 1426 |
class _EmptyClass(object): # helper for instance creation without calling __init__ |
1418 | 1427 |
pass |
1419 | 1428 | |
1420 |
- |