Вы должны создать миграцию данных. Подробнее о них см. В документах
Шаг 1 - создание пустых миграций данных
python manage.py makemigrations --empty yourappname
Шаг 2 - Добавить пользовательские sql для миграции:
# -*- coding: utf-8 -*-
# Generated by Django 1.11.14 on 2018-09-20 08:01
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('yourapp', '0001_name_of_depending_migration'),
]
operations = [
migrations.RunSQL(
sql="CREATE INDEX my_article_idx ON article (regexp_replace(url, '\?.*, ''))",
reverse_sql='DROP INDEX my_article_idx ON article'
)
]
Я экспериментировал с несколькими методами (спасибо всем, кто помогал), и вот что я придумал, используя jQuery. Кажется, он хорошо работает во всех протестированных мной браузерах. Смело берите его и используйте как хотите. Следующим шагом для меня будет превращение его в плагин jQuery многократного использования.
Я начал с обычной таблицы со всем в ней ( Id = "ladderTable" ) и написал Три метода - один для удаления первого столбца, один для удаления последнего столбца и один для фиксации высоты строк.
Метод stripFirstColumn создает новую таблицу ( Id = "nameTable" ), просматривает исходную таблицу, извлекает первый столбец и добавляет эти ячейки в nameTable.
Метод stripLastColumn делает в основном то же самое, за исключением того, что он извлекает последний столбец и добавляет ячейки в новую таблицу с именем totalTable .
Метод fixHeights просматривает каждую строку в каждой таблице, вычисляет максимальную высоту и применяет ее к связанным таблицам.
В событии готовности документа я вызвал все три метода по порядку. Обратите внимание, что все три таблицы перемещаются влево, поэтому они будут располагаться горизонтально.
<h1>Current Ladder</h1>
<div id="nameTableSpan" style="float:left;width:100px;border-right:2px solid gray;"></div>
<div id="ladderDiv" style="float:left;width:423px;overflow:auto;border:1px solid gray;margin-top:-1px;">
<table id="ladderTable" class="ladderTable">
<thead>
<tr><td>Name</td><td>Round 1</td> ... <td>Round 50</td><td class="scoreTotal">Total</td></tr>
</thead>
<tr><td>Bob</td><td>11</td> ... <td>75</td><td>421</td></tr>
... (more scores)
</table>
</div>
<div id="totalTableSpan" style="float:left;width:70px;border-left:2px solid gray;"></div>
function stripFirstColumn() {
// pull out first column:
var nt = $('<table id="nameTable" cellpadding="3" cellspacing="0" style="width:100px;"></table>');
$('#ladderTable tr').each(function(i)
{
nt.append('<tr><td style="color:'+$(this).children('td:first').css('color')+'">'+$(this).children('td:first').html()+'</td></tr>');
});
nt.appendTo('#nameTableSpan');
// remove original first column
$('#ladderTable tr').each(function(i)
{
$(this).children('td:first').remove();
});
$('#nameTable td:first').css('background-color','#8DB4B7');
}
function stripLastColumn() {
// pull out last column:
var nt = $('<table id="totalTable" cellpadding="3" cellspacing="0" style="width:70px;"></table>');
$('#ladderTable tr').each(function(i)
{
nt.append('<tr><td style="color:'+$(this).children('td:last').css('color')+'">'+$(this).children('td:last').html()+'</td></tr>');
});
nt.appendTo('#totalTableSpan');
// remove original last column
$('#ladderTable tr').each(function(i)
{
$(this).children('td:last').remove();
});
$('#totalTable td:first').css('background-color','#8DB4B7');
}
function fixHeights() {
// change heights:
var curRow = 1;
$('#ladderTable tr').each(function(i){
// get heights
var c1 = $('#nameTable tr:nth-child('+curRow+')').height(); // column 1
var c2 = $(this).height(); // column 2
var c3 = $('#totalTable tr:nth-child('+curRow+')').height(); // column 3
var maxHeight = Math.max(c1, Math.max(c2, c3));
//$('#log').append('Row '+curRow+' c1=' + c1 +' c2=' + c2 +' c3=' + c3 +' max height = '+maxHeight+'<br/>');
// set heights
//$('#nameTable tr:nth-child('+curRow+')').height(maxHeight);
$('#nameTable tr:nth-child('+curRow+') td:first').height(maxHeight);
//$('#log').append('NameTable: '+$('#nameTable tr:nth-child('+curRow+')').height()+'<br/>');
//$(this).height(maxHeight);
$(this).children('td:first').height(maxHeight);
//$('#log').append('MainTable: '+$(this).height()+'<br/>');
//$('#totalTable tr:nth-child('+curRow+')').height(maxHeight);
$('#totalTable tr:nth-child('+curRow+') td:first').height(maxHeight);
//$('#log').append('TotalTable: '+$('#totalTable tr:nth-child('+curRow+')').height()+'<br/>');
curRow++;
});
if ($.browser.msie)
$('#ladderDiv').height($('#ladderDiv').height()+18);
}
$(document).ready(function() {
stripFirstColumn();
stripLastColumn();
fixHeights();
$("#ladderDiv").attr('scrollLeft', $("#ladderDiv").attr('scrollWidth')); // scroll to the last round
});
Если у вас есть какие-либо вопросы или что-то непонятное, я обращаюсь к вам больше. чем рад помочь.
Мне потребовалось довольно много времени, чтобы понять, что нет ничего, что я мог бы использовать повторно, и мне потребовалось немного больше времени, чтобы написать это. Я бы не хотел, чтобы кто-то попал в такую же неприятность.
Могу ли я предложить несколько неортодоксальное решение?
Что вы думаете о размещении столбца «итого» после колонка «имя», а не в самом конце? Разве это не исключает необходимость прокручивать только часть таблицы?
Это не совсем то, о чем вы просите, но, возможно, это достаточное решение, учитывая, что альтернатива будет довольно грязной. (Например, размещение столбцов «total» и «name» вне таблицы создаст проблемы с выравниванием, когда не все строки имеют одинаковую высоту. Вы можете исправить это с помощью JavaScript, но тогда вы попадете в совершенно новый мир боль).
Кроме того, с точки зрения пользовательского интерфейса, может быть, что «имя» и «общее» являются наиболее важными данными, в этом случае имеет смысл объединить их, после чего следует своего рода «разбивка» по итогу. Конечно, у нас, кажется, есть интуиция, что «общее» должно следовать за его составными частями, но я не думаю, что это вызовет слишком большую путаницу для пользователя, если порядок будет изменен таким образом (хотя это вопрос для вы, основываясь на вашем продукте и ваших пользователях).
В любом случае, есть что рассмотреть.
РЕДАКТИРОВАТЬ:
Вот еще несколько неортодоксальных решений, теперь, когда я думаю, что немного лучше понимаю ваши намерения:
В любом случае, есть что рассмотреть.
РЕДАКТИРОВАТЬ:
Вот еще несколько неортодоксальных решений, теперь, когда мне кажется, что я немного лучше понимаю ваши намерения:
В любом случае, есть что рассмотреть.
РЕДАКТИРОВАТЬ:
Вот еще несколько неортодоксальных решений, теперь, когда мне кажется, что я немного лучше понимаю ваши намерения:
В любом случае, вы поняли идею. Возможно, лучше искать решение для пользовательского интерфейса, чем искаженное решение для разметки. В конечном счете, я бы задался вопросом, насколько важно представлять пользователю столько данных одновременно, что часть их должна прокручиваться определенным образом, чтобы данные были читаемыми. Возможно, вы создаете приложение для работы с электронными таблицами, и вам действительно нужно отображать матрицу 100x100 в одном представлении. Если нет, вы наверняка могли бы придумать более креативные способы, чем я, чтобы разделить результаты.
Сейчас оно не завершено (я просто очень быстро его смоделировал), но вот способ сделать это, используя прямой HTML. Вам нужны три таблицы ... две вне
и сам код:
<table style="float: left;">
<tr>
<td>Name</td>
</tr>
<tr>
<td>John</td>
</tr>
<tr>
<td>Will</td>
</tr>
</table>
<div id="tableWrapper" style="overflow-x: auto; width: 500px;float:left;padding-bottom: 10px;">
<table>
<tr>
<td>Score1</td>
<td>Score2</td>
...
</tr>
<tr>
<td>5</td>
<td>6</td>
...
</tr>
<tr>
<td>3</td>
<td>7</td>
...
</tr>
<tr>
<td>7</td>
<td>1</td>
...
</tr>
</table>
</div>
<table style="float: left;">
<tr>
<td>Total</td>
</tr>
<tr>
<td>86</td>
</tr>
<tr>
<td>82</td>
</tr>
</table>
Примечание. Нижний отступ элемента div предназначен для того, чтобы полоса прокрутки не закрывала таблицу в IE. Кроме того, ошибка, которую я должен решить, состоит в том, как указать ширину элементов заголовка внутри средней таблицы. По какой-то причине указание атрибута width = "" не работает. Таким образом, если текст элемента заголовка слишком широкий (и разбивается на другую строку), то макет разбивается (на одну строку)
Я полагаю, вы хотите прокрутить его только по горизонтали. В противном случае это может привести к путанице со статическими столбцами.
Вы можете поместить переполнение: auto только на содержащий элемент из внутренних ячеек таблицы ... Я не уверен, как браузеры справятся с этим, но вы можете поставить элементы, которые вы хотите зафиксировать внутри элементов thead и tfoot, и поместите прокручиваемую часть в элемент tbody и установите для его переполнения значение auto.
В противном случае вам может понадобиться отбросить семантику и кодировать левый столбец и правый столбец за пределами Таблица.
Лично я бы попробовал закодировать его как можно более семантическим, а затем использовать JavaScript для позиционирования левого и правого столбцов. Без JavaScript вы должны сделать так, чтобы он изящно перестал работать только с широкой таблицей (не уверен, насколько это будет сложно, как вы говорите, у вас фиксированная ширина)
Вы можете попробовать этот (грубый) пример jQuery, чтобы поместить значения первого столбца наружу.
var nameTable = '<table id="outside-name-col">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>'; // start making a table for name column only
$('#scoreTable tbody tr').each(function() { // iterate through existing table
var nameCol = $(this).find(':first'); // get column of index 0, i.e. first
var cellHeight = nameCol.height(); // get the height of this cell
$(this).find('td').height(cellHeight); // equalise the height across the row so removing this element will not collapse the height if it is taller than the scores and total
nameTable += '<tr><td style="height: ' + cellHeight + 'px">' + nameCol.html() + '</td></tr>'; // append the next row with new height and data
nameCol.remove(); // remove this cell from the table now it's been placed outside
});
nameTable += '</tbody></table>'; // finish table string
$('#scoreTable').before(nameTable); // insert just before the score table
Используйте CSS, чтобы расположить их для правильного выравнивания. Это не проверено, но оно должно дать вам некоторое представление.
Вы имели в виду горизонтальную прокрутку ??
Если вы хотите добиться горизонтальной прокрутки, тогда вы можете использовать 3 контейнера.
Прокрутка содержимого таблиц является проблематичной проблемой, поскольку для этого не существует простого и безопасного для браузера решения.
Лучший и самый безопасный способ сделать это требует JavaScript. Вы бы легко достигли даже горизонтальной прокрутки (это бесплатно) с помощью этой техники, которую я использовал. Вы можете легко преобразовать это в вашу проблему:
1) Я создал 3 таблицы
2) Поместил среднюю таблицу, в которой хранятся данные, внутри контейнера DIV
3) Установите стиль DIV на переполнение: auto
4) дал заголовок и таблицу нижнего колонтитула и div каждый шириной 100%
5) окружил все другим div для контроля общей ширины таблицы
6) убедился, что количество столбцов совпадает во всех три таблицы, и что все три имеют одинаковые стили в отношении отступов, поля и границы
теперь интересная часть:
6) ниже последнего элемента этой конструкции таблицы, напишите блок javascript (или включите его из файла)
7) напишите функцию, которая последовательно просматривает каждый столбец (используйте цикл for), начиная с первого. На каждой итерации этого цикла проверяйте ячейку td с первыми двумя таблицами в текущем столбце. Проверьте, какой из них больше, и назначьте его стилю меньшей ячейки TD. Возможно, вы захотите применить это значение и к таблице нижнего колонтитула.
8) вызвать эту функцию. Возможно, вы захотите сделать это через интервал или когда произойдут особые события, такие как новые данные в ячейках (например, при использовании ajax).
Примечание. При горизонтальной прокрутке размеры столбцов синхронизируются. Но вам придется синхронизировать позицию прокрутки таблицы верхнего и нижнего колонтитула с таблицей содержимого. В качестве альтернативы вы просто позволяете полному div прокручивать все по горизонтали, но не по вертикали. Это была бы работа DIV, которая содержит таблицу данных.
Этот метод очень хорошо работал во всех основных браузерах в проекте диаграммы Гопта с очень коплексом.
Примечание: Вы можете легко придумать эту концепцию под углом 90 градусов повернут таким образом, чтобы при прокрутке вы исправляли первый и последний столбец заголовка.
Редактировать: Вот еще один пример из моей базы кода, который может помочь вам найти решение:
var left_td = document.getElementById("left_td");
var right_td = document.getElementById("right_td");
var contentDiv = document.getElementById("contentDiv");
window.setInterval(function(){
var left_td_width = Math.round((parseInt(contentDIV.offsetWidth) - 120) / 2);
var right_td_width = (parseInt(contentDIV.offsetWidth) - left_td_width - 120;
left_td.style.width = left_td_width + "px";
right_td.style.width = right_td_width + "px";
}, 25);
Этот код выполняет следующие действия: , таблица с 3 столбцами всегда выглядит так: первый и последний столбцы имеют одинаковый размер, а центральный столбец имеет ширину 120 пикселей. В качестве альтернативы вы просто позволяете полному div прокручивать все по горизонтали, но не по вертикали. Это была бы работа DIV, которая содержит таблицу данных.
Этот метод очень хорошо работал во всех основных браузерах в проекте диаграммы Гопта с очень коплексом.
Примечание: Вы можете легко придумать эту концепцию под углом 90 градусов повернут таким образом, чтобы при прокрутке вы исправляли первый и последний столбец заголовка.
Редактировать: Вот еще один пример из моей базы кода, который может помочь вам найти решение:
var left_td = document.getElementById("left_td");
var right_td = document.getElementById("right_td");
var contentDiv = document.getElementById("contentDiv");
window.setInterval(function(){
var left_td_width = Math.round((parseInt(contentDIV.offsetWidth) - 120) / 2);
var right_td_width = (parseInt(contentDIV.offsetWidth) - left_td_width - 120;
left_td.style.width = left_td_width + "px";
right_td.style.width = right_td_width + "px";
}, 25);
Этот код выполняет следующие действия: , таблица с 3 столбцами всегда выглядит так: первый и последний столбцы имеют одинаковый размер, а центральный столбец имеет ширину 120 пикселей. В качестве альтернативы вы просто позволяете полному div прокручивать все по горизонтали, но не по вертикали. Это была бы работа DIV, которая содержит таблицу данных.
Этот метод очень хорошо работал во всех основных браузерах в проекте диаграммы Гопта с очень коплексом.
Примечание: Вы можете легко придумать эту концепцию под углом 90 градусов повернут таким образом, чтобы при прокрутке вы исправляли первый и последний столбец заголовка.
Редактировать: Вот еще один пример из моей базы кода, который может помочь вам найти решение:
var left_td = document.getElementById("left_td");
var right_td = document.getElementById("right_td");
var contentDiv = document.getElementById("contentDiv");
window.setInterval(function(){
var left_td_width = Math.round((parseInt(contentDIV.offsetWidth) - 120) / 2);
var right_td_width = (parseInt(contentDIV.offsetWidth) - left_td_width - 120;
left_td.style.width = left_td_width + "px";
right_td.style.width = right_td_width + "px";
}, 25);
Этот код выполняет следующие действия: , таблица с 3 столбцами всегда выглядит так: первый и последний столбцы имеют одинаковый размер, а центральный столбец имеет ширину 120 пикселей. Конечно, это не относится непосредственно к вашей особой проблеме, но может дать вам отправную точку в динамическом манипулировании таблицами с помощью JavaScript.