he tenido este problema con dos proyectos que he trabajado en el último momento. Para mi solución de ejemplo, tengo un "Formulario" que tiene muchas "Variables" asignadas y el orden de las variables en el formulario debe ser ordenable. Así que han puesto en práctica lo siguiente:
models.py
class Form(models.Model):
FormName = models.CharField(verbose_name="Form Name:", max_length=40)
VariableOrder = models.CommaSeparatedIntegerField(default="[]", editable=False)
def __unicode__(self):
return "%s" % (self.FormName)
class Variable(models.Model):
FormID = models.ForeignKey(Form, default=0, editable=False, related_name="Variable")
VarName = models.CharField(max_length=32, verbose_name="Name of variable in the database:")
def __unicode__(self):
return "%s" % self.VarName
La clave de lo alto es el VariableOrder CommaSeparatedIntegerField es donde vamos a guardar el orden de las variables de la hoja, y vamos a utilícelo como una lista de Python, por lo que el valor predeterminado es [].
Para la plantilla, renderizo mis Variables en un archivo que vamos a hacer arrastrar y soltar (los elementos de lista que realmente uso tienen mucho más estilo relacionado con CSS e información sobre la variable).
<ul id="sortable">
{% for Variable in VarList %}
<li id="{{ Variable.id }}">{{ Variable }}</li>
{% endfor %}
</ul>
Ahora vamos a hacer que la lista se arrastre y suelte para cambiar el orden. para que esto funcione es necesario tener el fragmento de AJAX CSRF de Django sitio en la cabeza
$(function() {
$("#sortable").sortable({
placeholder: "ui-state-highlight",
update: function(event, ui){
$.ajax({
type:"POST",
url:"{% url builder.views.variableorder %}",
data: {Order: JSON.stringify($('#sortable').sortable('toArray')) },
success: function(data){
// Do stuff here - I don't do anything.
}
});
}
});
$("#sortable").disableSelection();
});
La parte importante anterior es que "actualizar" llama a la función cada vez que hay un cambio de posición de cualquiera de los variables, que envía el AJAX. toArray on sortable junto con el stringify de JSON nos permite enviar los id de arriba a abajo de cada variable, que la vista utiliza de la siguiente manera. Nota: Guardo el objeto Form activo como una variable de sesión, pero en otro caso solo necesitaría llamar al objeto Form que deseaba cambiar el orden de.
def variableorder(request):
if request.is_ajax():
Order = request.POST['Order']
updateOrder = request.session['FormID']
updateOrder.VariableOrder = newOrder
updateOrder.save()
request.session['FormID'] = Form.objects.get(id=updateOrder.id)
return HttpResponse("Order changed.")
else:
pass
La clave de todo esto es que se puede utilizar este CommaSeparatedIntegerField como una lista mediante la evaluación de la cadena.Por ejemplo:
Adición de una variable:
aForm = Form.objects.get(id=1)
currentOrder = aForm.VariableOrder
currentOrder = eval(currentOrder)
newVar = Variable(stuff in here)
newVar.save()
currentOrder.append(newVar.id)
aForm.VariableOrder = currentOrder
aForm.save()
Extracción de una variable:
aForm = Form.objects.get(id=1)
currentOrder = aForm.VariableOrder
currentOrder = eval(currentOrder)
# Variable ID that we want to delete = 3
currentOrder.remove(3)
aForm.VariableOrder = currentOrder
aForm.save()
Rendering las variables para:
aForm = Form.objects.get(id=1)
currentOrder = aForm.VariableOrder
currentOrder = eval(currentOrder)
VarList = []
for i in currentOrder:
VarList.append(Variable.objects.get(id=i))
Este es un primer borrador aproximado de lo que voy a usar, pero me está funcionando bien. La primera mejora obvia es la evaluación de que la lista de Python es un método en la clase. p.ej.
def getVarOrder(self):
return eval(self.VariableOrder)
y luego a llamarlo Form.getVarOrder() cuando se quiere manipular la lista. En cualquier caso, con suerte esto ayuda.
JD
Nice. Me recuerda los números de línea en BASIC. :-) –