Elecciones dinámicas en el campo del modelo.
Frecuentes
Visto 401 veces
0
I want my models to have order
field, which will contain order of an item among all items of its kind.
Y quiero usar choices
dentro de eso IntegerField
, which would contain all the numbers of currently existing items in that table.
So it would need to be dynamic choices.
How do I load all existing "order" values of all existing items in a table, and use this list for choices?
2 Respuestas
3
It sounds like you want to build a manager for your model:
modelos.py
from django.db import models
class OrderManager(models.Manager):
def order_choices(self):
return [(i, i) for i in OrderModel.objects.values_list('order', flat=True)]
class OrderModel(models.Model):
objects = OrderManager()
order = models.IntegerField()
class Meta:
ordering = ['order']
def __unicode__(self):
return '%i' % self.order
formularios.py
from django import forms
from yourapp.models import OrderModel
class OrderModelForm(forms.ModelForm):
order = forms.ChoiceField(choices=OrderModel.objects.order_choices())
class Meta:
model = OrderModel
administrador.py
from django.contrib import admin
from yourapp.forms import OrderModelForm
from yourapp.models import OrderModel
class OrderModelAdmin(admin.ModelAdmin):
form = OrderModelForm
admin.site.register(OrderModel, OrderModelAdmin)
Editar
Managers are use to make general model queries without having an instance of a model object. If you don't understand the concept of managers, you can still refactor the code out of the manager class, stick it somewhere else and import that function across your code. Managers allow you to abstract custom general queryset that you can reuse. See more details https://docs.djangoproject.com/en/dev/topics/db/managers/
The code without the manager will look like
views.py or some other file
from app.models import OrderModel
def order_choices():
return [(i, i) for i in OrderModel.objects.values_list('order', flat=True)]
From anywhere in your code, if you want to reuse the above multiple times:
from app.views import oder_choices
order_choices()
Opuesto a:
from app.models import OderModel
OrderModel.objects.order_choices()
If you only want to use the above once, you can leave it in the forms.py
as shown in the other answer. It's really up to you on how you want to refactor your code.
Respondido el 24 de diciembre de 12 a las 05:12
I understand forms.py and admin.py, but why would (in this solution) I need a custom manager? Won't I achieve what is desired by just using custom form? If I want to order items by the "order" value, I could do that without the manager, can't I? - tonino.j
I thought you wanted a way to find that list from the model as from your previous comment which explains the use of the manager. You can re-clarify your question if its original meaning has changed so that we can answer it properly. - Thierry Lam
Yes, I do want to load/create CHOICES list from all currently existing models in the database. However, I just need this info in the select box in the form. (or in the possible choices in the model itself, so it validates properly on model level, not form level - even better). But if I achieve this with custom form - so I get desired values in my select box, then what is the meaning of the manager? Please, elaborate your solution a bit, I am a bit lost. I upvoted it, but I don't fully understand it. - tonino.j
I think this can be done without any manager. I understand managers to a degree, but I can simply load the select choices with list comprehension: CHOICES = [(item.order, item.order) for item in MyModel.objects.all()] - tonino.j
Thats why I asked why I would need manager when I already need to create custom forms.py - tonino.j
1
Dont add the choices directly to the model, add them to a form represnting the model later, by overriding the field with a set of choices.
than, do something like:
class MyForm(..):
myfield_order_field = IntegerField(choices = [(i,i) for range(MyModel.objects.count)])
class Meta():
model = MyModel
if you want to use it in the admin, add to your Admin Class:
class MyModelAdmin(admin.ModelAdmin):
...
form = MyForm
it will override this field in the admin too.
Respondido el 23 de diciembre de 12 a las 13:12
I understand, but I want the select field to be available in the admin, too. So doing it properly in the model is the way to go, I think. - tonino.j
But is there a way to call Model.objects.all() form the model definition? Is is possible to get that list from model? I'll accept this, if I dont find other way. - tonino.j
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas django django-models or haz tu propia pregunta.
Vea este question and check answer given by
danihp
- Aamir RindMaybe I would use it if I could in any way understand what it does. - tonino.j