def get(self, request, slug, form=None, conflict_errors=None): event = self.get_event(slug, request) if isinstance(event, http.HttpResponse): return event if not self.can_view_event(event, request): return self.cant_view_event(event, request) if not self.can_edit_event(event, request): return self.cant_edit_event(event, request) initial = self.event_to_dict(event) if form is None: form = forms.EventEditForm(initial=initial, event=event) if not request.user.has_perm('main.change_recruitmentmessage'): del form.fields['recruitmentmessage'] context = { 'event': event, 'form': form, 'previous': json.dumps(initial), 'conflict_errors': conflict_errors, } if 'thumbnail_url' in initial: context['thumbnail_url'] = initial['thumbnail_url'] context['revisions'] = (EventRevision.objects.filter( event=event).order_by('-created').select_related('user')) return render(request, self.template_name, context)
def post(self, request, slug): event = self.get_event(slug, request) if isinstance(event, http.HttpResponse): return event if not self.can_view_event(event, request): return self.cant_view_event(event, request) if not self.can_edit_event(event, request): return self.cant_edit_event(event, request) previous = request.POST['previous'] previous = json.loads(previous) form = forms.EventEditForm(request.POST, request.FILES, event=event) base_revision = None if form.is_valid(): if not EventRevision.objects.filter(event=event).count(): base_revision = EventRevision.objects.create_from_event(event) cleaned_data = form.cleaned_data if 'placeholder_img' in request.FILES: cleaned_data['picture'] = None changes = {} conflict_errors = [] for key, value in cleaned_data.items(): # figure out what the active current value is in the database if key == 'placeholder_img': if (event.picture and 'placeholder_img' not in request.FILES): current_value = event.picture.file.url else: if event.placeholder_img: current_value = event.placeholder_img.url else: current_value = None elif key == 'tags': current_value = ', '.join(x.name for x in event.tags.all()) elif key == 'channels': current_value = [x.pk for x in event.channels.all()] elif key == 'picture': current_value = event.picture.id if event.picture else None elif key == 'event_id': pass else: current_value = getattr(event, key) if key == 'recruitmentmessage': if current_value: current_value = current_value.pk if key == 'channels': prev = set( [Channel.objects.get(pk=x) for x in previous[key]]) value = set(value) for channel in prev - value: event.channels.remove(channel) for channel in value - prev: event.channels.add(channel) if prev != value: changes['channels'] = { 'from': ', '.join(sorted(x.name for x in prev)), 'to': ', '.join(sorted(x.name for x in value)) } elif key == 'tags': value = set( [x.strip() for x in value.split(',') if x.strip()]) prev = set([ x.strip() for x in previous['tags'].split(',') if x.strip() ]) for tag in prev - value: tag_obj = Tag.objects.get(name=tag) event.tags.remove(tag_obj) for tag in value - prev: try: tag_obj = Tag.objects.get(name__iexact=tag) except Tag.DoesNotExist: tag_obj = Tag.objects.create(name=tag) except Tag.MultipleObjectsReturned: tag_obj, = Tag.objects.filter(name__iexact=tag)[:1] event.tags.add(tag_obj) if prev != value: changes['tags'] = { 'from': ', '.join(sorted(prev)), 'to': ', '.join(sorted(value)) } elif key == 'placeholder_img': if value: changes[key] = { 'from': (event.placeholder_img and event.placeholder_img.url or ''), 'to': '__saved__event_placeholder_img' } event.placeholder_img = value elif key == 'recruitmentmessage': prev = event.recruitmentmessage event.recruitmentmessage = value if value != prev: changes[key] = { 'from': prev, 'to': event.recruitmentmessage } elif key == 'event_id': pass else: if value != previous[key]: changes[key] = {'from': previous[key], 'to': value} setattr(event, key, value) if key in changes: # you wanted to change it, but has your reference changed # since you loaded it? previous_value = previous.get(key) if previous_value != current_value: conflict_errors.append(key) continue if conflict_errors: return self.get(request, slug, form=form, conflict_errors=conflict_errors) elif changes: event.save() EventRevision.objects.create_from_event( event, user=request.user, ) else: if base_revision: base_revision.delete() return redirect('main:event', event.slug) return self.get(request, slug, form=form)