【问题标题】:Fullcalendar Event save on click - DjangoFullcalendar 事件点击保存 - Django
【发布时间】:2020-02-06 16:16:24
【问题描述】:

我想这对于了解 JavaScript 的人来说是相当简单的,但我自己无法弄清楚。

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

我可以使用 Django 表单添加事件,这没有问题,但我想在点击时保存事件,正如我之前所说的。所以用户点击所需的时间,绘制事件“气泡”并让点击关闭。所以当那个事件被绘制的时候,需要直接保存到数据库或者传递给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'),
...

【问题讨论】:

    标签: javascript django django-forms fullcalendar fullcalendar-4


    【解决方案1】:

    我认为您正在以一种过于复杂的方式进行尝试。如果您使用 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 服务器。当然你需要在你的urls和views代码中添加ajax view。

    【讨论】:

    • 嗯,我会试试的。所以基本上,url或视图应该是我的add_event函数?
    • 你的问题我不清楚:你需要一个视图来显示日历,你需要一个 ajax 视图来添加事件。
    • 这是一个问题还是一个陈述?你说'你需要在你的 url 中添加 ajax 视图并查看代码',但我已经有一个函数和 ajax 调用,正如你在我的 views.py 中看到的那样。那么,我是否需要再次将该 url 传递给 ajax 呢?
    • ajax 调用必须在 JS 中,我没看到。而且您的视图函数似乎不适合通过 ajax 调用。
    • 哦,对不起,我想说,你写的这个ajax。实际上,对于视图的逻辑,这就是我需要帮助的原因..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 2012-03-10
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多