Difficulty performing data CRUD with Fullcalendar and Django/Python

Asked

Viewed 742 times

5

I’m trying to use the FullCalendar in my project Django and I’m having a hard time doing the data crud.

I would like everything to work on the same screen, that is, when the user selects dates in the calendar, the modal appears to enter the values (title and dates), when he clicks on an event, the modal appears to edit the event and a button to remove it.

So far what I’ve managed to do is this::

<script>

$(document).ready(function () {

    $('#calendar').fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
        navLinks: true, // can click day/week names to navigate views
        editable: true,
        eventLimit: true, // allow "more" link when too many events
        selectable: true,
        selectHelper: true,
        select: function (start, end) {
            $('#cadastrar #start').val(moment(start).format('DD/MM/YYYY HH:mm:ss'));
            $('#cadastrar #end').val(moment(end).format('DD/MM/YYYY HH:mm:ss'));
            $('#cadastrar').modal('show');
        },
    });

});

<script>

In my template (agenda/agenda.html) I did this, which corresponds to the agenda and modal that is opened when some date is selected in the calendar.


<section class="content">
     <div id='calendar'></div>

    <div class="modal fade" id="cadastrar" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
         data-backdrop="static">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                            aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title text-center">Cadastrar Evento</h4>
                </div>
                <div class="modal-body">
                    <form role="form" action="" method="post">
                        {% csrf_token %}
                          <div class="form-group">
                              {{form.event_name}}
                          </div>
                          <div class="form-group">
                              {{form.start_date}}
                          </div>
                          <div class="form-group">
                              {{form.end_date}}
                          </div>
                          <div class="form-group">
                              {{form.event_type}}
                          </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</section>

In py.models created the following

class Evento(models.Model):
    event_name = models.CharField(max_length=255, null=True, blank=True)
    start_date = models.DateTimeField(null=True, blank=True)
    end_date = models.DateTimeField(null=True, blank=True)
    event_type = models.CharField(max_length=10, null=True, blank=True)

    def __str__(self):
        return self.event_name

And these are my views


class AdicionarEventoView(CustomCreateView):
    form_class = EventoForm
    template_name = "agenda/agenda.html"
    permission_codename = 'add_evento'

    def get_success_message(self, cleaned_data):
        return self.success_message % dict(cleaned_data, descricao=self.object.descricao)

    def get_context_data(self, **kwargs):
        context = super(AdicionarEventoView, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        return super(AdicionarEventoView, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)

        if form.is_valid():
            self.object = form.save(commit=False)
            self.object.save()
            return self.form_valid(form)

        return self.form_invalid(form)

class EventosListView(CustomListView):
    template_name = 'agenda/agenda.html'
    model = Evento
    context_object_name = 'all_eventos'
    permission_codename = 'view_eventos'

    def get_context_data(self, **kwargs):
        context = super(EventosListView, self).get_context_data(**kwargs)
        return context


class EditarEventoView(CustomUpdateView):
    form_class = EventoForm
    model = Evento
    template_name = "agenda/agenda.html"
    success_message = "Evento editado com sucesso."
    permission_codename = 'change_evento'

    def get_success_message(self, cleaned_data):
        return self.success_message % dict(cleaned_data, descricao=self.object.descricao)

    def get_context_data(self, **kwargs):
        context = super(EditarEventoView, self).get_context_data(**kwargs)
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.get_form_class()
        form = form_class(request.POST, instance=self.object)

        if form.is_valid():
            self.object = form.save()
            return self.form_valid(form)

        return self.form_invalid(form)

And finally the urls

   url(r'agenda/adicionar/$',
        views.AdicionarEventoView.as_view(), name='addeventoview'),

    url(r'agenda/$',
        views.EventosListView.as_view(), name='listaeventosview'),

    url(r'agenda/editar/(?P<pk>[0-9]+)/$',
        views.EditarEventoView.as_view(), name='editarservicoview'),

How do I call the modal so that I can register, edit and delete events? So far modal opens, but no information appears. The problem is certainly in view, but how do I get it to Create, Edit and Delete on the same page and in the same modal?

  • 1

    Eai Rafael, dude I have a project on github that I do a scheduling system with Python Django using Full Calendar. If you want to take a look [https://github.com/khalilmlk/api]. It will solve your doubts about what you want to do.

1 answer

1


Your problem is with Javascript, not Python.

You need to return your HTML only once (for example, at endpoint /home or /), from there you manage the business logic in frontend, and to create CRUD you send Ajax calls to your controllers in Django, in endpoints (/event/add, event/{id}, event/{id}/edit, event/{id}/delete). Your views should only return JSON, with the information needed to update the parts of the interface you want, and in Javascript itself you write a callback to process Django’s results and update your interface without reloading the page.

In short, you don’t need a view for each event. Manage events in Javascript directly, and consider using Vue or React instead of jQuery (you can do it with jQuery, but it’s harder if your project grows).

I won’t write code here because I would have to practically rewrite the whole structure, but there’s a good tutorial here: https://quickadminpanel.com/blog/laravel-fullcalendar-edit-events-with-bootstrap-modal/

The tutorial is not in Django (it is in Laravel), but I believe you could easily implement it in Django, since the frontend does not change from one to the other.

The most important part of the tutorial for your question is this one:

$(document).ready(function() {
    // ... All the calendar functionality

    $('#appointment_update').click(function(e) {
        e.preventDefault();
        var data = {
            _token: '{{ csrf_token() }}',
            appointment_id: $('#appointment_id').val(),
            start_time: $('#start_time').val(),
            finish_time: $('#finish_time').val(),
        };

        $.post('{{ route('admin.appointments.ajax_update') }}', data, function( result ) {
            $('#calendar').fullCalendar('removeEvents', $('#event_id').val());

            $('#calendar').fullCalendar('renderEvent', {
                title: result.appointment.client.first_name + ' ' + result.appointment.client.last_name,
                start: result.appointment.start_time,
                end: result.appointment.finish_time
            }, true);

            $('#editModal').modal('hide');
        });
    });
});

Browser other questions tagged

You are not signed in. Login or sign up in order to post.