单击时保存全日历事件 - Django

Fullcalendar Event save on click - Django

我想这对于了解 JavaScript 的人来说是相当简单的,但我自己就是想不通。

我已经在我的 Django 应用程序中实现了 FullCalendar,我想要的是简单的用户点击事件保存(在用户操作、点击释放和绘制事件之后将事件保存到数据库)。

我可以使用 Django 表单添加事件,这没有问题,但我想在点击时保存事件,正如我之前所说的。所以用户点击所需的时间,绘制事件 'bubble' 并让点击关闭。所以当那个事件被绘制时,需要直接保存到数据库或者传递给Django表单。

我对 JS 的经验不多,所以请不要介意我。

提前致谢。

PS:我再说一遍,一切正常,我可以添加事件、删除事件等等,但只能使用我的表单。

让我们从 zakazi.html(创建所有事件的页面)开始:

{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% load static %}
{% block title %} Zakaži {% endblock title %}



{% block content_row %}

    <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
          integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
            integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
            crossorigin="anonymous"></script>


    {{ form.media }}


    {% include 'main/partials/_link_fullcalendar.html' %} # all the cdn's for fullcalendar(link tags)


    <div style="display: flex; width: 100%; margin: 0 auto;text-align: center">

        <div class="container" style="width: 350px;">
            <div class="row">
                <div class="col">
                    <form method="post" action="{% url 'main:add_event' opp.pk %}">
                        {{ form|crispy }}
                        {% csrf_token %}
                        <button type="submit" class="btn btn-primary">Potvrdi</button>
                    </form>
                </div>
            </div>
        </div>

        <div class="container"
             style="display: flex; overflow-x: scroll; height: 750px; width: max-content;">
            {% if calendars %}
                {% for cal in calendars %}
                    <script>
                        document.addEventListener('DOMContentLoaded', function () {
                            let calendarEl = document.getElementById('{{ cal.id }}');
                            //////////////////////////////////////////////////////////////////////////////////////////////
                            let calendar1 = new FullCalendar.Calendar(calendarEl, {
                                minTime: "07:00:00",
                                maxTime: "22:00:00",
                                businessHours: {
                                    startTime: '09:00', // a start time (10am in this example)
                                    endTime: '21:00', // an end time (6pm in this example)
                                },
                                height: 'auto',
                                locale: 'sr',
                                plugins: ['dayGrid', 'timeGrid', 'list', 'interaction'],
                                defaultView: 'timeGridDay',
                                header: {
                                    left: 'today',
                                    center: '{{ cal.name|title }}',
                                    right: 'timeGridDay,dayGridWeek,timeGridThreeDay'
                                },
                                views: {
                                    timeGridThreeDay: {
                                        type: 'timeGrid',
                                        duration: {days: 3},
                                        buttonText: '3 Dana'
                                    }
                                },
                                navLinks: false, // can click day/week names to navigate views
                                select: function (arg) {
                                    let title = prompt('Naziv posla');
                                    if (title) {
                                        calendar.addEvent({
                                            title: title,
                                            start: arg.start,
                                            end: arg.end,
                                            allDay: arg.allDay
                                        })
                                    }
                                    calendar.unselect()
                                },
                                editable: true,
                                selectable: true,
                                selectMirror: true,
                                eventLimit: true, // allow "more" link when too many events
                                eventTextColor: 'black',
                                events: [
                                    {% for i in events %}
                                        {% if i.calendar_id == cal.id %}
                                            {
                                                id: "{{ i.event_id }}",
                                                calendar: "{{ i.calendar }}",
                                                calendar_id: "{{ i.calendar_id }}",
                                                title: "{{ i.event_name}}",
                                                start: '{{ i.start_date|date:"Y-m-d" }}T{{ i.start_date|time:"H:i" }}',
                                                end: '{{ i.end_date|date:"Y-m-d" }}T{{ i.end_date|time:"H:i" }}',

                                            },
                                        {% endif %}
                                    {% endfor %}
                                ]
                            });
                            //////////////////////////////////////////////////////////////////////////////////////////////
                            calendar1.render();
                            //////////////////////////////////////////////////////////////////////////////////////////////
                        })
                        ;
                    </script>
                {% endfor %}
            {% endif %}

            <div style="display: flex; height: 1000px" class="container">
                {% for cal in calendars %}
                    <p>{{ cal.name|title }}{{ cal.id }}</p>
                    <div class="container" id='{{ cal.id }}'></div>
                {% endfor %}
            </div>
        </div>
    </div>

    <!---------------------------------------------- FULLCALENDAR SCRIPT----------------------------------------------->
    {% include 'main/partials/_fullcalendar_script.html' %}
    <!---------------------------------------------- FULLCALENDAR SCRIPT END ------------------------------------------>
{% endblock content_row %}

我的 views.py(all_events 和 add_events 函数):

#################################################### EVENTS #########################################################
def events(request):
    all_events = Events.objects.all()
    get_event_types = Events.objects.only('event_type')
    calendars = Calendar.objects.all()

    if request.GET:
        event_arr = []
        if request.GET.get('event_type') == "all":
            all_events = Events.objects.all()
        else:
            all_events = Events.objects.filter(event_type__icontains=request.GET.get('event_type'))

        for i in all_events:
            event_sub_arr = {}
            event_sub_arr['id'] = i.event_id
            event_sub_arr['calendar'] = i.calendar
            event_sub_arr['calendar_id'] = i.calendar.id
            event_sub_arr['title'] = i.event_name
            start_date = datetime.strptime(str(i.start_date.date()), "%Y-%m-%dT%H:%M:%S").strftime("%Y-%m-%dT%H:%M:%S")
            end_date = datetime.strptime(str(i.end_date.date()), "%Y-%m-%dT%H:%M:%S").strftime("%Y-%m-%dT%H:%M:%S")
            event_sub_arr['start'] = start_date
            event_sub_arr['end'] = end_date
            event_arr.append(event_sub_arr)
        return HttpResponse(json.dumps(event_arr))

    context = {
        "calendars": calendars,
        "events": all_events,
        "get_event_types": get_event_types,

    }
    return render(request, 'main/selectable.html', context)


################################################## ADD EVENTS #########################################################
def add_event(request, pk):
    opp = get_object_or_404(OpportunityList, pk=pk)
    events_all = Events.objects.all()
    calendars = Calendar.objects.all()

    opp_locked = get_object_or_404(Locked, pk=pk)
    user = User.objects.get(username=request.user.username)

    form = AddEventForm() 

    if request.method == 'POST':
        form = AddEventForm(request.POST or None)

        if form.is_valid():
            event = Events.objects.create(
                event_name=form.cleaned_data['event_name'],
                event_comment=form.cleaned_data['event_comment'],
                status=form.cleaned_data['status'],
                start_date=form.cleaned_data['start_date'],
                end_date=form.cleaned_data['end_date'],
                calendar=form.cleaned_data['calendar'],
                opp_eluid=int(opp_locked.locked_eluid.eluid),
                zakazan=True,
                added_by=user,
            )
            opp_locked.opp_comment = form.cleaned_data['event_comment']
            opp_locked.is_locked = False
            opp_locked.zakazan = True
            opp_locked.save()
            event.save()

            messages.success(request, '...' + opp_locked.opp_comment)

            return redirect('opportunity:optika')

    context = {
        'form': form,
        'opp': opp,
        'events': events_all,
        "calendars": calendars
    }
    return render(request, 'opportunity/detalji/zakazi.html', context) # html for adding events to calendar, where the form is 

表格:

class ZakaziForma(forms.ModelForm):
    class Meta:
        model = Events
        fields = ['event_name', 'event_comment', 'status', 'start_date', 'end_date', 'calendar',
                  'opp_eluid']

        labels = {
            'event_name': 'Naziv Posla:',
            'event_comment': 'Komentar:',
            'status': 'Status:',
            'start_date': 'Početak:',
            'end_date': 'Završetak:',
            'calendar': 'Kalendar',
        }

        widgets = {
            'start_date': DateTimePicker(options={'useCurrent': True, 'collapse': False},
                                         attrs={'icon-toggle': True, }),
            'end_date': DateTimePicker(options={'useCurrent': True, 'collapse': False}),
            'opp_eluid': forms.HiddenInput(),
        }

我的网址:

...
    path('calendar/dodaj/<int:pk>', add_event, name='add_event'),
...

我认为您尝试的方式太复杂了。如果您使用 fullcalender 和 jquery,您只需在脚本代码中添加如下内容:

$(document).ready(function() {
    $('#calendar').fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay',

        },

        defaultView: 'agendaWeek',
        navLinks: true, 
        selectable: true,
        selectHelper: true,
        select: function(start, end) {

                title='new';
                if (title) {
                eventData = {
                    title: title,
                    start: start,
                    end: end,
                    backgroundColor: '#00ff00',
                };
                $('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
            }
            $.ajax({ url: '/addevent/',
        data: {
          'start': start,
          'end': end,
        },
      });

;
...here you need to addd the code that draws the events

那么发生的事情是 JS 在浏览器中呈现事件并通过 ajax 调用将数据发送到 django 服务器。当然,您需要在您的网址和视图代码中添加 ajax 视图。