我有一个django报告表格,基本上就像这里的表格:
class EntryForm(ModelForm):
year = forms.IntegerField()
month = forms.ModelChoiceField(queryset = ... )
report_category = form.ModelChoiceField(queryset = ... ) # FKey to some category model
report_text = forms.CharField()
最初,用户会在文本输入框中输入年份值,选择月份,然后选择类别并输入报告。
现在我希望月份下拉列表中包含尚未有报告的月份列表。在2014年1月提交报告后,下次用户输入2014年时,下拉列表将仅填充11个月(减去1月份)。
我知道如何完成查询集,但是在文本输入失去焦点之后,我仍然对如何在下拉列表中更改jQuery / AJAX感到困惑。
答案 0 :(得分:3)
这是一个有效的例子:
from django.db import models
#min and max values for integer fields
from django.core.validators import MinValueValidator, MaxValueValidator
class CategoryModel(models.Model):
category = models.CharField(max_length=20, unique=True)
def __unicode__(self):
return u"%s" % self.category
class EntryModel(models.Model):
year = models.IntegerField(validators=[MinValueValidator(1900), MaxValueValidator(2100)])
month = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(12)])
report_category = models.ForeignKey(CategoryModel, blank=True, null=True, on_delete=models.SET_NULL)
report_text = models.CharField(max_length=100, blank=True, null=True, default=None)
from django import forms
from models import CategoryModel, EntryModel
class EntryForm(forms.ModelForm):
months = (
('1','January'),
('2','February'),
('3','March'),
('4','April'),
('5','May'),
('6','June'),
('7','July'),
('8','August'),
('9','September'),
('10','October'),
('11','November'),
('12','December'),
)
month = forms.ChoiceField(choices=months)
#hidden control used to populate the month drop down list
month_hidden=forms.ChoiceField(choices=months)
report_category = forms.ModelChoiceField(queryset = CategoryModel.objects.all())
class Meta:
model=EntryModel
from django.conf.urls import patterns, url
from views import EntryCreateView
urlpatterns=patterns('so_23711764.views',
url(r'^/?$', EntryCreateView.as_view(), name='display_entry'),
url(r'^reload_controls.html$', 'reload_controls_view', name='reload_controls'),
)
# Create your views here.
from django.views.generic.edit import CreateView
from models import EntryModel
from forms import EntryForm
#use json for the ajax request
from django.http import HttpResponse
from django.utils import simplejson
class EntryCreateView(CreateView):
model = EntryModel
form_class=EntryForm
template_name = "so_23711764/index.html"
#~ fields = ['name']
#view called with ajax to reload the month drop down list
def reload_controls_view(request):
context={}
#get the year that the user has typed
year=request.POST["year"]
#get months without reports (months to be displayed in the drop down list)
context["months_to_display"]=list(EntryModel.objects.filter(year=year, report_category__isnull=True).values_list('month', flat=True).distinct())
return HttpResponse(simplejson.dumps(context), mimetype="application/json")
<!-- css of the application -->
<link rel="stylesheet" href="{{STATIC_URL}}css/so_23711764.css?{% now 'U' %}" />
<form id="entry_form" method="post" action="{% url display_entry %}">
{% csrf_token %}
{{ form.as_p }}
<!-- in urls.py, set the path to the view reload_controls -->
<div id="reload_controls_view" style="display: none;">{% url reload_controls %}</div>
</form>
<!-- jquery -->
<script type="text/javascript" src="{{ STATIC_URL }}jquery.min.js"></script>
<!-- csrf file to avoid 403 (FORBIDDEN) on ajax views -->
<script type="text/javascript" src="{{ STATIC_URL }}csrf.js"></script>
<!-- js related to the application -->
<script type="text/javascript" src="{{ STATIC_URL }}js/so_23711764.js?{% now 'U' %}"></script>
/* bind the event to the form, so it still works after controls are reloaded with ajax */
$('#entry_form').on('blur', '#id_year', function()
{
reload_controls(this.value);
});
/* update the month drop down list with ajax */
function reload_controls(year)
{
$.ajax
({
type: 'POST',
url: $("#reload_controls_view").text(),
dataType: 'json',
data: "year="+year,
success: function(result)
{
//empty month drop down list
$("#id_month").empty()
//add months with no report
$.each( result.months_to_display, function( index, value )
{
//use the hidden drop down list to populate the month field
month=$("#id_month_hidden option[value='" + value + "']").text()
//add months to the drop down list
$('#id_month').append('<option value="'+value+'">'+month+'</option>')
});
},
error: function(xhr, status, error)
{
window.console&&console.log(xhr.responseText);
}
});
}
/* hide month_hidden control */
#id_month_hidden, label[for="id_month_hidden"]
{
display: none;
}
现在,如果我访问页面http://127.0.0.1:8000/so_23711764/
(django开发服务器),我得到:
使用此条目模型表:
如果我输入&#34; 2014&#34;对于这一年,当控制失去焦点时,我得到:
希望它有所帮助:)。