我有一个模型的更新视图,这个模型与另一个模型有很多关系。由于一些过滤要求,我创建了一个自定义的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( .. )
答案 0 :(得分:2)
这会解决您的问题吗?
self.fields['m2m_field'] = forms.MultipleChoiceField(choices = choices,
widget = FilteredSelectMultiple("M2M", False, choices = choices),
required=False)