具有multiplechoicefield的Django UpdateView表单在发布时会形成in_valid而不选择多选字段?

时间:2017-11-06 15:42:07

标签: django django-forms

我有一个模型的更新视图,这个模型与另一个模型有很多关系。由于一些过滤要求,我创建了一个自定义的multiplechoicefield并通过修改form_valid来保存它。但如果未选择此多选字段,则表单将发布到form_invalid。此字段不是必需的。我的观点和形式如下:

 (function () {
        "use strict";
        $(function () {

            var image, appending, imageCanvas, imageCanvasContext, lineCanvas, lineCanvasContext, pointLifetime, points = [];

            function start() {
                document.addEventListener('mousemove', onMouseMove);
                window.addEventListener('resize', resizeCanvases);
                appending.appendChild(imageCanvas);
                resizeCanvases();
                tick();
            }

            function onMouseMove(event) {
                var scroll = 0;
                if (!$(".search-popup").length) scroll = $(document).scrollTop();
                points.push({
                    time: Date.now(),
                    x: event.clientX,
                    y: event.clientY + scroll
                });
            }

            function resizeCanvases() {
                setTimeout(function () {
                    var c = setInterval(function () {
                        if ($(".hero-header canvas").length) {
                            imageCanvas.width = lineCanvas.width = $(".hero-header canvas").parent().width();
                            imageCanvas.height = lineCanvas.height = $(".hero-header canvas").parent().height();
                        }
                    }, 1);
                    setTimeout(function () {
                        clearInterval(c);
                    }, 200);
                }, 2000);
            }

            function tick() {
                points = points.filter(function (point) {
                    var age = Date.now() - point.time;
                    return age < pointLifetime;
                });
                drawLineCanvas();
                drawImageCanvas();
                requestAnimationFrame(tick);
            }

            function drawLineCanvas() {
                var minimumLineWidth = 40;
                var maximumLineWidth = 100;
                var lineWidthRange = maximumLineWidth - minimumLineWidth;
                var maximumSpeed = 50;
                lineCanvasContext.clearRect(0, 0, lineCanvas.width, lineCanvas.height);
                lineCanvasContext.lineCap = 'round';
                lineCanvasContext.shadowBlur = 20;
                lineCanvasContext.shadowColor = '#000';
                for (var i = 1; i < points.length; i++) {
                    var point = points[i];
                    var previousPoint = points[i - 1];
                    var distance = getDistanceBetween(point, previousPoint);
                    var speed = Math.max(0, Math.min(maximumSpeed, distance));
                    var percentageLineWidth = (maximumSpeed - speed) / maximumSpeed;
                    lineCanvasContext.lineWidth = minimumLineWidth + percentageLineWidth * lineWidthRange;
                    var age = Date.now() - point.time;
                    var opacity = (pointLifetime - age) / pointLifetime;
                    lineCanvasContext.strokeStyle = 'rgba(0, 0, 0, ' + opacity + ')';
                    lineCanvasContext.beginPath();
                    lineCanvasContext.moveTo(previousPoint.x, previousPoint.y);
                    lineCanvasContext.lineTo(point.x, point.y);
                    lineCanvasContext.stroke();
                }
            }

            function getDistanceBetween(a, b) {
                return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
            }

            function drawImageCanvas() {
                var top = 0,
                    left = 0;
                var width = imageCanvas.width;
                var height = imageCanvas.width / image.naturalWidth * image.naturalHeight;
                if (height < imageCanvas.height) {
                    width = imageCanvas.height / image.naturalHeight * image.naturalWidth;
                    height = imageCanvas.height;
                    left = -(width - imageCanvas.width) / 2;
                } else {
                    top = -(height - imageCanvas.height) / 2;
                }
                imageCanvasContext.clearRect(0, 0, imageCanvas.width, imageCanvas.height);
                imageCanvasContext.globalCompositeOperation = 'source-over';
                imageCanvasContext.drawImage(image, left, top, width, height);
                imageCanvasContext.globalCompositeOperation = 'destination-in';
                imageCanvasContext.drawImage(lineCanvas, 0, 0);
            }

            function addCanvasEffect() {
                image = document.querySelector('.clear-image');
                appending = document.querySelector('.bg-container');
                imageCanvas = document.createElement('canvas');
                imageCanvasContext = imageCanvas.getContext('2d');
                lineCanvas = document.createElement('canvas');
                lineCanvasContext = lineCanvas.getContext('2d');
                pointLifetime = 1000;
                points = [];
                if (image.complete) {
                    start();
                } else {
                    image.onload = start;
                }
            }

            function setCanvasEffect() {
                var href = window.location.href;
                var dir = href.substring(0, href.lastIndexOf('/')) + "/";
                var bgImage;
                var cElement;
                if ($(".h-video").length) cElement = $(".h-video");
                else if ($(".h-slideshow").length) cElement = $(".h-slideshow");
                else if ($(".hero-header").not(".login-popup,.review-popup,.pm-popup").length) cElement = $(".hero-header").not(".login-popup,.review-popup,.pm-popup");
                bgImage = cElement.find(".hero-image").css("background-image");
                if (bgImage !== "none") {
                    bgImage = bgImage.replace(dir, "");
                    bgImage = bgImage.replace(' ', "").replace(' ', "").replace(' ', "").replace(' ', "").replace(' ', "");
                    bgImage = bgImage.replace('url(\"', "").replace("url(\'", "").replace("url(", "").replace('")', "");
                    bgImage = bgImage.replace("')", "").replace(")", "");
                    cElement.append('<div class="bg-container bg-media"><img class="clear-image" src="' + bgImage + '"></div>');
                    addCanvasEffect();
                }
            }       

            var he = ".hero-header ",
                temp, he_ = $(".hero-header"),
                color_skin = $("<div class='dumb'>").appendTo("body").addClass("color_skin").css("background-color");
            $(".dumb").remove();

            he_.prepend('<div class="hero-image"></div>');
            he_.prepend('<div class="overlay"></div>');
            he_.prepend('<div class="dot-overlay"></div>');
            if ($(".masked").length) $(".masked").prepend('<div class="hero-mask"></div>');
            if ($(".texture").length) $(".texture").prepend('<div class="hero-texture"></div>');
            $(he).not(".search-popup").find(".overlay").css({
                display: "block"
            });

            setCanvasEffect();              

        });
    })();

..................表格......................

class Updatemodel(UpdateView):
    template_name = ...

    def get_success_url(self):
        return .. 

    def get_from_class(self):
        .. ..

    def form_valid(self,form):
        kwargs = super(Updatemodel, self).get_form_kwargs()
        m2m_initial = kwargs['instance'].model_m2m.filter( .. )
        chosen_m2m = model_m2m.objects.filter(pk__in = form.cleaned_data.get('model_m2m'))
        m2m_add = chosen_m2m.exclude(pk__in = m2m_initial.values_list('pk, flat = True))
        m2m_remove = m2m_initial.exclude(pk__in = chosen_m2m.values_list('pk,flat = True))
        form.instance.model_m2m.add(*m2m_add)
        form.instance.model_m2m.remove(*m2m_remove)

        return super(Updatemodel, self).form_valid(form)

    def get_form_kwargs(self):
         kwargs = super(Updatemodel, self).get_form_kwargs()
         kwargs['m2m_initial'] = kwargs['instance'].model_m2m.filter( ..)
         kwargs['m2m'] = model_m2m.objects.all().filter( .. )

1 个答案:

答案 0 :(得分:2)

这会解决您的问题吗?

self.fields['m2m_field'] = forms.MultipleChoiceField(choices = choices, 
                               widget = FilteredSelectMultiple("M2M", False, choices = choices), 
                               required=False)