Nullable ForeignKeys и удаление образцового экземпляра, на который ссылаются,

gl_FragCoord - это встроенные входные переменные, необязательно объявлять входную переменную gl_FragCoord. Координаты x и y являются оконными (пиксельными) координатами.
Нижний левый угол gl_FragCoord равен (0,5, 0,5), а верхний правый равен (W-0,5, H-0,5), где W и H ширина и высота области просмотра.

Необходимо сопоставить gl_FragCoord.x с диапазоном [minX, maxX] и gl_FragCoord.y с диапазоном [minY, maxy].
Для этого я рекомендую нам функцию GLSL mix .
Предполагается, что viewportDimensions содержит координаты с и высоту окна просмотра в координатах окна (пикселя).

vec2 c = mix(vec2(minX, minY), vec2(maxX, maxY), gl_FragCoord.xy / viewportDimensions.xy);

См. Пример (WebGL), где я применил предложения к фрагментному шейдеру вопроса.
Границы инициализируются следующим образом

minX = -2.5
minY = -2.0
maxX =  1.5
maxY =  2.0 

(function loadscene() {    

var canvas, gl, vp_size, prog, bufObj = {};

function initScene() {

    canvas = document.getElementById( "ogl-canvas");
    gl = canvas.getContext( "experimental-webgl" );
    if ( !gl )
      return;

    progDraw = gl.createProgram();
    for (let i = 0; i < 2; ++i) {
        let source = document.getElementById(i==0 ? "draw-shader-vs" : "draw-shader-fs").text;
        let shaderObj = gl.createShader(i==0 ? gl.VERTEX_SHADER : gl.FRAGMENT_SHADER);
        gl.shaderSource(shaderObj, source);
        gl.compileShader(shaderObj);
        let status = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS);
        if (!status) alert(gl.getShaderInfoLog(shaderObj));
        gl.attachShader(progDraw, shaderObj);
        gl.linkProgram(progDraw);
    }
    status = gl.getProgramParameter(progDraw, gl.LINK_STATUS);
    if ( !status ) alert(gl.getProgramInfoLog(progDraw));
    progDraw.inPos = gl.getAttribLocation(progDraw, "inPos");
    progDraw.minX = gl.getUniformLocation(progDraw, "minX");
    progDraw.maxX = gl.getUniformLocation(progDraw, "maxX");
    progDraw.minY = gl.getUniformLocation(progDraw, "minY");
    progDraw.maxY = gl.getUniformLocation(progDraw, "maxY");
    progDraw.viewportDimensions = gl.getUniformLocation(progDraw, "viewportDimensions");
    gl.useProgram(progDraw);

    var pos = [ -1, -1, 1, -1, 1, 1, -1, 1 ];
    var inx = [ 0, 1, 2, 0, 2, 3 ];
    bufObj.pos = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, bufObj.pos );
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( pos ), gl.STATIC_DRAW );
    bufObj.inx = gl.createBuffer();
    bufObj.inx.len = inx.length;
    gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufObj.inx );
    gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( inx ), gl.STATIC_DRAW );
    gl.enableVertexAttribArray( progDraw.inPos );
    gl.vertexAttribPointer( progDraw.inPos, 2, gl.FLOAT, false, 0, 0 ); 
    
    gl.enable( gl.DEPTH_TEST );
    gl.clearColor( 0.0, 0.0, 0.0, 1.0 );

    window.onresize = resize;
    resize();
    requestAnimationFrame(render);
}

function resize() {
    //vp_size = [gl.drawingBufferWidth, gl.drawingBufferHeight];
    vp_size = [window.innerWidth, window.innerHeight];
    //vp_size = [256, 256]
    canvas.width = vp_size[0];
    canvas.height = vp_size[1];
}

function render(deltaMS) {

    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
   
    gl.uniform1f(progDraw.minX, -2.5);
    gl.uniform1f(progDraw.minY, -2.0);
    gl.uniform1f(progDraw.maxX, 1.5);
    gl.uniform1f(progDraw.maxY, 2.0);
    gl.uniform2f(progDraw.viewportDimensions, canvas.width, canvas.height);
    gl.drawElements( gl.TRIANGLES, bufObj.inx.len, gl.UNSIGNED_SHORT, 0 );
    
    requestAnimationFrame(render);
}  

initScene();

})();
[112]
html,body { margin: 0; overflow: hidden; }




[1136 ]

7
задан Eli Courtwright 25 March 2009 в 13:41
поделиться

1 ответ

Django действительно эмулирует SQL ON DELETE CASCADE поведение, и нет зарегистрированного способа никакого out-of-the поля изменить это. Документы, где они упоминают это, около конца этого раздела: Удаление объектов.

Вы правы, что Django собирает все связанные образцовые экземпляры, затем называет предварительно удалить обработчик для каждого. Отправитель сигнала будет образцовым классом, собирающимся быть удаленным в этом случае Message, вместо User, который мешает обнаруживать различие между каскадным удалением, инициированным Пользователем, и нормальное удаляют... тем более, что сигнал для удаления Пользовательского класса является последним, так как это - последнее удаление :-)

Можно, однако, получить список объектов, что Django предлагает удалить перед вызовом User.delete () функцию. Каждому образцовому экземпляру назвали полузакрытый метод _collect_sub_objects() это составляет список экземпляров с внешними ключами, указывающими на него (это составляет этот список, не удаляя экземпляры). Вы видите, как этот метод называют путем взгляда на delete() в django.db.base.

Если бы это было одним из Ваших собственных объектов, то я рекомендовал бы переопределить delete() метод на Вашем экземпляре, чтобы выполнить _collect_sub_objects () и затем повредить ForeignKeys прежде, чем назвать суперкласс удаляет. Так как Вы используете встроенный объект Django, который можно найти слишком трудным для разделения на подклассы (хотя возможно заменить собственным Пользовательским объектом django's), Вам, вероятно, придется положиться выставленная для обозрения логика для выполнения _collect_sub_objects и повредите FKs перед удалением.

Вот быстрый-и-грязный пример:

from django.db.models.query import CollectedObjects
u = User.objects.get(id=1)


instances_to_be_deleted = CollectedObjects()
u._collect_sub_objects(instances_to_be_deleted)

for k in instances_to_be_deleted.ordered_keys():
    inst_dict = instances_to_be_deleted.data[k]
    for i in inst_dict.values():
        i.sender = None  # You will need a more generic way for this
        i.save()

u.delete()
13
ответ дан 6 December 2019 в 19:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: