agendas: fix import when unknown field found (#42523)
This commit is contained in:
parent
cc6da3d0a8
commit
19af0088ff
|
@ -15,6 +15,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
import datetime
|
||||
import math
|
||||
import requests
|
||||
|
@ -24,6 +25,7 @@ import uuid
|
|||
import django
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Group
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models, transaction
|
||||
from django.db.models import Count, Q, Case, When
|
||||
|
@ -63,6 +65,17 @@ def generate_slug(instance, **query_filters):
|
|||
return slug
|
||||
|
||||
|
||||
def clean_import_data(cls, data):
|
||||
cleaned_data = copy.deepcopy(data)
|
||||
for param in data:
|
||||
try:
|
||||
cls._meta.get_field(param)
|
||||
except FieldDoesNotExist:
|
||||
# remove unknown fields
|
||||
cleaned_data.pop(param)
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class ICSError(Exception):
|
||||
pass
|
||||
|
||||
|
@ -243,6 +256,7 @@ class Agenda(models.Model):
|
|||
data[permission + '_role'] = Group.objects.get(name=permissions[permission])
|
||||
except Group.DoesNotExist:
|
||||
raise AgendaImportError(_('Missing "%s" role') % permissions[permission])
|
||||
data = clean_import_data(cls, data)
|
||||
agenda, created = cls.objects.get_or_create(slug=data['slug'], defaults=data)
|
||||
if not created:
|
||||
for k, v in data.items():
|
||||
|
@ -387,6 +401,7 @@ class TimePeriod(models.Model):
|
|||
|
||||
@classmethod
|
||||
def import_json(cls, data):
|
||||
data = clean_import_data(cls, data)
|
||||
return cls(**data)
|
||||
|
||||
def export_json(self):
|
||||
|
@ -490,6 +505,7 @@ class MeetingType(models.Model):
|
|||
|
||||
@classmethod
|
||||
def import_json(cls, data):
|
||||
data = clean_import_data(cls, data)
|
||||
meeting_type, created = cls.objects.get_or_create(
|
||||
slug=data['slug'], agenda=data['agenda'], defaults=data
|
||||
)
|
||||
|
@ -624,6 +640,7 @@ class Event(models.Model):
|
|||
data['start_datetime'] = make_aware(
|
||||
datetime.datetime.strptime(data['start_datetime'], '%Y-%m-%d %H:%M:%S')
|
||||
)
|
||||
data = clean_import_data(cls, data)
|
||||
if data.get('slug'):
|
||||
event, created = cls.objects.get_or_create(slug=data['slug'], defaults=data)
|
||||
if not created:
|
||||
|
@ -754,6 +771,7 @@ class Desk(models.Model):
|
|||
def import_json(cls, data):
|
||||
timeperiods = data.pop('timeperiods', [])
|
||||
exceptions = data.pop('exceptions', [])
|
||||
data = clean_import_data(cls, data)
|
||||
instance, created = cls.objects.get_or_create(slug=data['slug'], agenda=data['agenda'], defaults=data)
|
||||
if not created:
|
||||
for k, v in data.items():
|
||||
|
@ -1005,6 +1023,7 @@ class TimePeriodException(models.Model):
|
|||
for k, v in data.items():
|
||||
if k.endswith('_datetime'):
|
||||
data[k] = import_datetime(v)
|
||||
data = clean_import_data(cls, data)
|
||||
return cls(**data)
|
||||
|
||||
def export_json(self):
|
||||
|
|
|
@ -287,3 +287,50 @@ def test_import_export_desk_missing_fields(app, meetings_agenda):
|
|||
import_site(payload)
|
||||
assert TimePeriod.objects.exists() is False
|
||||
assert TimePeriodException.objects.exists() is False
|
||||
|
||||
|
||||
def test_import_export_desk_unknown_fields(app, some_data, meetings_agenda):
|
||||
# add exception to meeting agenda
|
||||
desk = meetings_agenda.desk_set.first()
|
||||
tpx_start = make_aware(datetime.datetime(2017, 5, 22, 8, 0))
|
||||
tpx_end = make_aware(datetime.datetime(2017, 5, 22, 12, 30))
|
||||
TimePeriodException.objects.create(desk=desk, start_datetime=tpx_start, end_datetime=tpx_end)
|
||||
# add permissions
|
||||
group1 = Group.objects.create(name=u'group1')
|
||||
group2 = Group.objects.create(name=u'group2')
|
||||
meetings_agenda.view_role = group1
|
||||
meetings_agenda.edit_role = group2
|
||||
meetings_agenda.save()
|
||||
# add event
|
||||
Event.objects.create(
|
||||
agenda=meetings_agenda, start_datetime=make_aware(datetime.datetime.now()), places=10
|
||||
)
|
||||
|
||||
output = get_output_of_command('export_site')
|
||||
payload = json.loads(output)
|
||||
|
||||
Agenda.objects.all().delete()
|
||||
assert Agenda.objects.exists() is False
|
||||
assert MeetingType.objects.exists() is False
|
||||
assert Desk.objects.exists() is False
|
||||
assert TimePeriod.objects.exists() is False
|
||||
assert TimePeriodException.objects.exists() is False
|
||||
|
||||
# add unknown fields everywhere
|
||||
for agenda in payload['agendas']:
|
||||
agenda['unknown_field'] = 'foobar'
|
||||
if 'meetingtypes' in agenda:
|
||||
agenda['meetingtypes'][0]['unknown_field'] = 'foobar'
|
||||
if 'desks' in agenda:
|
||||
agenda['desks'][0]['unknown_field'] = 'foobar'
|
||||
agenda['desks'][0]['timeperiods'][0]['unknown_field'] = 'foobar'
|
||||
agenda['desks'][0]['exceptions'][0]['unknown_field'] = 'foobar'
|
||||
if 'events' in agenda:
|
||||
agenda['events'][0]['unknown_field'] = 'foobar'
|
||||
|
||||
import_site(payload)
|
||||
assert Agenda.objects.exists() is True
|
||||
assert MeetingType.objects.exists() is True
|
||||
assert Desk.objects.exists() is True
|
||||
assert TimePeriod.objects.exists() is True
|
||||
assert TimePeriodException.objects.exists() is True
|
||||
|
|
Loading…
Reference in New Issue