Sto affrontando un problema molto strano in uno dei miei progetti di Django. Nel mio progetto ho una classe di campo personalizzata che gestisce le chiavi esterne, uno a uno e molti altri due campi del modello. La classe è qualcosa come la seguente.Django Attributi del campo personalizzato che effettuano query di database
from django import forms
class CustomRelatedField(forms.Field):
def __init__(self, model, limit=None, multiple=False, create_objects=True, *args, *kwargs):
self.model = model
self.limit = limit
self.multiple = multiple
self.create_objects = create_objects
super(CustomRelatedField, self).__init__(*args, **kwargs)
def clean(self, value):
""" Calls self.get_objects to get the actual model object instance(s)
from the given unicode value.
"""
# Do some value processing here
return self.get_objects(value)
def get_objects(self, values):
""" Returns the model object instances for the given unicode values.
"""
results = []
for value in values:
try:
obj = self.model.object.get_or_create(name=value)[0]
results.append(obj)
except Exception, err:
# Log the error here.
return results
def prepare_value(self, value):
""" Returns the value to be sent to the UI. The value
passed to this method is generally the object id or
a list of object id's (in case it is a many to many object).
So we need to make a database query to get the object and
then return the name attribute.
"""
if self.multiple:
result = [obj.name for obj in self.model.filter(pk__in=value)]
else:
result = self.model.object.get(pk=value)
return result
Recentemente, mentre stavo giocando con la django-toolbar, ho scoperto che una delle pagine che ha un modulo con i campi di cui sopra è stato ridicolmente rendendo più query per gli stessi oggetti più e più volte.
Durante il debug, ho scoperto il metodo prepare_value
era stato chiamato ancora e ancora. Dopo un po 'di debug, ho capito che il colpevole era il modello. Ho un modello generico che uso per forme, Sembra qualcosa di simile al seguente:
{% for field in form %}
{% if field.is_hidden %}
<!-- Do something here -->
{% endif %}
{% if field.field.required %}
<!-- Do something here -->
{% endif %}
<label>{{ field.label }}</label>
<div class="form-field">{{ field }}</div>
{% if field.field.widget.attrs.help_text %}
<!-- Do something here -->
{% elif field.errors %}
<!-- Do something here -->
{% endif %}
{% endfor %}
Nel codice sopra, ogni if
dichiarazione chiama la classe campo che chiama il metodo prepare_value
che poi rende le query di database. Ognuno dei seguenti elencati sta facendo una query sul database, sono totalmente perso dal motivo per cui questo sta accadendo e non ho idea di nessuna soluzione. Qualsiasi aiuto, suggerimenti sarebbe molto apprezzato. Grazie.
- field.is_hidden
- field.field.required
- field.label
- field.label_tag
- campo
- field.field.widget.attrs.help_text
- campo. errori
Inoltre, perché non t il suo accadere solo con la mia classe campo personalizzata, altri campi (FK, O2O, M2M) nell'applicazione e l'amministratore dell'applicazione, basta fare una query, anche se stanno usando un modello simile.
Quale versione di django stai usando? – aquavitae
Versione Django - (1, 5, 5, 'finale', 0) – Amyth