Select2 with Django 不接受选择
Select2 with Django not accepting selections
几天来我一直在研究这个问题,我只是被难住了。尝试在不使用 django-select2 应用程序的情况下集成 Select2.js。
我的模型:
from django.contrib.auth import get_user_model
from django.db import models
import datetime as dt
from WHST.settings import PROCESS_LEVELS
class CEID(models.Model):
process = models.CharField(max_length=4,
choices=PROCESS_LEVELS)
ceid = models.CharField(max_length=6)
representative = models.ManyToManyField(get_user_model(), blank=True)
functional_area = models.CharField(max_length=200)
score = models.IntegerField(null=True, blank=True)
ceid_is_production = models.BooleanField(default=True)
ceid_is_front_end = models.BooleanField(default=True)
ceid_is_hidden = models.BooleanField(default=False)
ceid_pdl = models.ManyToManyField('PDL', blank=True)
user_edited = models.BooleanField(default=False)
def __str__(self):
return str(self.process) + ' ' + str(self.ceid) if self.ceid else ''
def __unicode__(self):
return str(self.process) + ' ' + str(self.ceid) if self.ceid else ''
class Meta:
ordering = ('process', 'ceid', 'process',)
def calculate_ceid_score(self):
entities = Entity.objects.filter(
ceid__id=self.id).filter(production=True)
score = 0
for entity in entities:
score += entity.score if entity.score else 0
self.score = score / len(entities) if len(entities) > 0 else 0
self.save()
return
我的看法:
from datetime import datetime, timedelta
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.db.models import Sum, Q
from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.views import View
from django.views.generic import ListView, TemplateView, FormView, UpdateView
from django_filters.views import FilterView
from django.contrib.auth import get_user_model
from dal import autocomplete
from pages.filter import CeidFilter, PmRunInformationFilter, HomePageFilter
from pages.forms import PDLAddForm, PagesAdminSetCeidUserAssociationForm, AreaAutofillSearchForm
from tools.models import CEID, Entity, WaferHandlingType, PmRunInformation, ToolPm
class PagesAdminSetCeidUserAssociation(LoginRequiredMixin, View, UserPassesTestMixin):
template_name = 'pages/pages_admin_set_ceid_user_association.html'
login_url = '/login/'
def test_func(self):
return self.request.user.is_superuser
def get(self, request):
form = PagesAdminSetCeidUserAssociationForm()
if request.is_ajax():
if request.GET.get('dat_type') == 'representatives':
representatives = get_user_model().objects.filter(
username__icontains=request.GET.get('term')
)
representative_response_content = list(
representatives.values())
return JsonResponse(representative_response_content, safe=False)
elif request.GET.get('dat_type') == 'ceids':
ceids = CEID.objects.filter(
ceid__icontains=request.GET.get('term')
)
ceid_response_content = list(ceids.values())
return JsonResponse(ceid_response_content, safe=False)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = PagesAdminSetCeidUserAssociationForm(request.POST or None)
if form.is_valid():
print(form)
pass
# form.save()
return HttpResponseRedirect(reverse('pages_home_page'))
return render(request, self.template_name, {'form': form})
我的表格:
from django import forms
from tools.models import PDL, CEID
from django.contrib.auth import get_user_model
from django.conf import settings
class PagesAdminSetCeidUserAssociationForm(forms.ModelForm):
representative = forms.MultipleChoiceField(label='WHST Representative')
ceid = forms.MultipleChoiceField(label='CEID')
class Meta:
model = CEID
fields = ['representative', 'ceid']
def __init__(self, *args, **kwargs):
super(PagesAdminSetCeidUserAssociationForm, self).__init__(*args, **kwargs)
# self.fields['representative'].queryset = get_user_model().objects.none()
# self.fields['ceid'].queryset = CEID.objects.none()
for field in self.fields:
self.fields[field].widget.attrs = {'class': 'form-control'}
if 'ceid' in self.data:
ceid = self.data.get('ceid')
self.fields['ceid'].queryset = CEID.objects.filter(ceid__in=ceid).order_by()
if 'representative' in self.data:
rep = self.data.get('representative')
self.fields['representative'].queryset = get_user_model().objects.filter(username__in=rep)
最后,我的模板:
{% extends 'base.html' %} {% load crispy_forms_tags %}
{% block title %}User CEID Association{% endblock %}
{% block content %}
<form novalidate method="post" action="{% url 'pages_admin_set_ceid_user_association' %}" >
{% csrf_token %} {{ form|crispy }}
<input type="submit" class="btn btn-success" value="Update" /><a
href="{% url 'pages_home_page' %}"
><button type="button" class="btn btn-primary">Go Back</button></a
>
</form>
<script>
$('#id_representative').select2({
ajax: {
url: '{% url 'pages_admin_set_ceid_user_association' %}',
dataType: 'json',
data: function(params) {
return {
q: params.term,
term: params.term,
_type: params._type,
dat_type: 'representatives'
}
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
return {id: item.id, text: item.username + ' (' + item.first_name + ' ' + item.last_name + ')'};
})
};
}
},
minimumInputLength: 3
});
$('#id_ceid').select2({
ajax: {
url: '{% url 'pages_admin_set_ceid_user_association' %}',
dataType: 'json',
data: function(params) {
return {
q: params.term,
term: params.term,
_type: params._type,
dat_type: 'ceids'
}
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
console.log(item)
return {id: item.id, text: item.process + ' ' + item.ceid};
})
};
}
},
minimumInputLength: 3
});
</script>
{% endblock content %}
当我尝试提交时,出现以下错误:
枚举是:
PROCESS_LEVELS = [('1270', '1270'), ('1272', '1272'), ('1274', '1274'), ('1222', '1222')]
我已经尝试为 forms.MultipleChoiceField 设置选项,但这并没有解决问题。我试过将字段切换为 CharField 和 ChoiceField,但这也没有解决问题。我也尝试过在表单中删除和添加 novalidate,但这没有任何作用。任何帮助将不胜感激!
找到解决问题的方法:
在我的表单中,我创建了一个自定义多项选择字段:
class CustomMultipleChoiceField(forms.MultipleChoiceField):
"""This field is a MultipleChoiceField designed to override the validation method of a default MultipleChoiceField
"""
def validate(self, value):
return value
这绕过了常规的表单验证程序。然后我将该自定义字段设置为我表单中的字段,并将其从 ModelForm 转换为常规表单:
class PagesAdminSetCeidUserAssociationForm(forms.Form):
representative = CustomMultipleChoiceField(label='WHST Representative')
ceid = CustomMultipleChoiceField(label='CEID')
class Meta:
model = CEID
fields = ['representative', 'ceid']
def __init__(self, *args, **kwargs):
super(PagesAdminSetCeidUserAssociationForm,
self).__init__(*args, **kwargs)
# self.fields['representative'].queryset = get_user_model().objects.none()
# self.fields['ceid'].queryset = CEID.objects.none()
for field in self.fields:
self.fields[field].widget.attrs = {'class': 'form-control'}
if 'ceid' in self.data:
ceid = self.data.get('ceid')
self.fields['ceid'].queryset = CEID.objects.filter(
ceid__in=ceid).order_by()
if 'representative' in self.data:
rep = self.data.get('representative')
self.fields['representative'].queryset = get_user_model(
).objects.filter(username__in=rep)
之后,编写我的 post 请求以按每个输入的 ID 进行过滤是一件简单的事情:
class PagesAdminSetCeidUserAssociation(LoginRequiredMixin, View, UserPassesTestMixin):
template_name = 'pages/pages_admin_set_ceid_user_association.html'
login_url = '/login/'
def test_func(self):
return self.request.user.is_superuser
def get(self, request):
form = PagesAdminSetCeidUserAssociationForm()
if request.is_ajax():
if request.GET.get('dat_type') == 'representatives':
representatives = get_user_model().objects.filter(
username__icontains=request.GET.get('term')
)
representative_response_content = list(
representatives.values())
return JsonResponse(representative_response_content, safe=False)
elif request.GET.get('dat_type') == 'ceids':
ceids = CEID.objects.filter(
ceid__icontains=request.GET.get('term')
)
ceid_response_content = list(ceids.values())
return JsonResponse(ceid_response_content, safe=False)
elif request.GET.get('dat_type') == 'user-ceid-association-container':
representative = get_user_model().objects.get(id=request.GET.get('term[]'))
ceids = list(CEID.objects.filter(representative=representative))
print(ceids)
ceid_name_list = []
for ceid in ceids:
ceid_name_list.append(ceid.__str__())
print(ceid_name_list)
response = {
'representative': representative.username + ' ( ' + representative.first_name + ' ' + representative.last_name + ' )',
'ceids': ceid_name_list,
}
return JsonResponse(response, safe=False)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = PagesAdminSetCeidUserAssociationForm(request.POST or None)
if form.is_valid():
for ceid in CEID.objects.filter(id__in=form.cleaned_data['ceid']):
ceid.representative.set(get_user_model().objects.filter(id__in=form.cleaned_data['representative']))
return render(request, self.template_name, {'form': form})
还有我的 html 代码:
{% extends 'base.html' %} {% load crispy_forms_tags %} {% block title %}User
CEID Association{% endblock %} {% block content %}
<h3>Please note, submitting associate will reset assignment of CEIDs</h3>
<form method="post" action="{% url 'pages_admin_set_ceid_user_association' %}">
{% csrf_token %} {{ form|crispy }}
<input type="submit" class="btn btn-success" value="Update" /><a
href="{% url 'pages_home_page' %}"
><button type="button" class="btn btn-primary">Go Back</button></a
>
</form>
<div
id="user-ceid-association-container"
class="container"
style="display: none"
>
<div class="card mb-4 shadow-sm">
<div class="card-body">
<h6 class="card-text" id="User"></h6>
<ul class="card-text" id="ceids"></ul>
</div>
</div>
</div>
<script>
$('#id_representative').select2({
ajax: {
url: '{% url 'pages_admin_set_ceid_user_association' %}',
dataType: 'json',
data: function(params) {
return {
q: params.term,
term: params.term,
_type: params._type,
dat_type: 'representatives'
}
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
return {id: item.id, text: item.username + ' (' + item.first_name + ' ' + item.last_name + ')'};
})
};
}
},
minimumInputLength: 3
});
$('#id_representative').change(function () {
let representative_value = $(this).val();
$.ajax({
url: '{% url 'pages_admin_set_ceid_user_association' %}',
data: {
'term': representative_value,
'dat_type': 'user-ceid-association-container',
},
success: function(result) {
$('#user-ceid-association-container').css('display', 'block');
$('#User').text(result.representative);
$('#ceids').empty();
if (result.ceids.length > 0) {
for(let i=0; i < result.ceids.length; i++) {
$('#ceids').append('<li class="card-text">' + result.ceids[i] + '</li>');
}}
else {
$('#ceids').append('<li class="card-text">This user has no CEIDs associated to them</li>');
}
return
},
});
});
$('#id_ceid').select2({
ajax: {
url: '{% url 'pages_admin_set_ceid_user_association' %}',
dataType: 'json',
data: function(params) {
return {
q: params.term,
term: params.term,
_type: params._type,
dat_type: 'ceids'
}
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
console.log(item)
return {id: item.id, text: item.process + ' ' + item.ceid};
})
};
}
},
minimumInputLength: 3
});
</script>
{% endblock content %}
这似乎已经成功了!
几天来我一直在研究这个问题,我只是被难住了。尝试在不使用 django-select2 应用程序的情况下集成 Select2.js。 我的模型:
from django.contrib.auth import get_user_model
from django.db import models
import datetime as dt
from WHST.settings import PROCESS_LEVELS
class CEID(models.Model):
process = models.CharField(max_length=4,
choices=PROCESS_LEVELS)
ceid = models.CharField(max_length=6)
representative = models.ManyToManyField(get_user_model(), blank=True)
functional_area = models.CharField(max_length=200)
score = models.IntegerField(null=True, blank=True)
ceid_is_production = models.BooleanField(default=True)
ceid_is_front_end = models.BooleanField(default=True)
ceid_is_hidden = models.BooleanField(default=False)
ceid_pdl = models.ManyToManyField('PDL', blank=True)
user_edited = models.BooleanField(default=False)
def __str__(self):
return str(self.process) + ' ' + str(self.ceid) if self.ceid else ''
def __unicode__(self):
return str(self.process) + ' ' + str(self.ceid) if self.ceid else ''
class Meta:
ordering = ('process', 'ceid', 'process',)
def calculate_ceid_score(self):
entities = Entity.objects.filter(
ceid__id=self.id).filter(production=True)
score = 0
for entity in entities:
score += entity.score if entity.score else 0
self.score = score / len(entities) if len(entities) > 0 else 0
self.save()
return
我的看法:
from datetime import datetime, timedelta
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.db.models import Sum, Q
from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.views import View
from django.views.generic import ListView, TemplateView, FormView, UpdateView
from django_filters.views import FilterView
from django.contrib.auth import get_user_model
from dal import autocomplete
from pages.filter import CeidFilter, PmRunInformationFilter, HomePageFilter
from pages.forms import PDLAddForm, PagesAdminSetCeidUserAssociationForm, AreaAutofillSearchForm
from tools.models import CEID, Entity, WaferHandlingType, PmRunInformation, ToolPm
class PagesAdminSetCeidUserAssociation(LoginRequiredMixin, View, UserPassesTestMixin):
template_name = 'pages/pages_admin_set_ceid_user_association.html'
login_url = '/login/'
def test_func(self):
return self.request.user.is_superuser
def get(self, request):
form = PagesAdminSetCeidUserAssociationForm()
if request.is_ajax():
if request.GET.get('dat_type') == 'representatives':
representatives = get_user_model().objects.filter(
username__icontains=request.GET.get('term')
)
representative_response_content = list(
representatives.values())
return JsonResponse(representative_response_content, safe=False)
elif request.GET.get('dat_type') == 'ceids':
ceids = CEID.objects.filter(
ceid__icontains=request.GET.get('term')
)
ceid_response_content = list(ceids.values())
return JsonResponse(ceid_response_content, safe=False)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = PagesAdminSetCeidUserAssociationForm(request.POST or None)
if form.is_valid():
print(form)
pass
# form.save()
return HttpResponseRedirect(reverse('pages_home_page'))
return render(request, self.template_name, {'form': form})
我的表格:
from django import forms
from tools.models import PDL, CEID
from django.contrib.auth import get_user_model
from django.conf import settings
class PagesAdminSetCeidUserAssociationForm(forms.ModelForm):
representative = forms.MultipleChoiceField(label='WHST Representative')
ceid = forms.MultipleChoiceField(label='CEID')
class Meta:
model = CEID
fields = ['representative', 'ceid']
def __init__(self, *args, **kwargs):
super(PagesAdminSetCeidUserAssociationForm, self).__init__(*args, **kwargs)
# self.fields['representative'].queryset = get_user_model().objects.none()
# self.fields['ceid'].queryset = CEID.objects.none()
for field in self.fields:
self.fields[field].widget.attrs = {'class': 'form-control'}
if 'ceid' in self.data:
ceid = self.data.get('ceid')
self.fields['ceid'].queryset = CEID.objects.filter(ceid__in=ceid).order_by()
if 'representative' in self.data:
rep = self.data.get('representative')
self.fields['representative'].queryset = get_user_model().objects.filter(username__in=rep)
最后,我的模板:
{% extends 'base.html' %} {% load crispy_forms_tags %}
{% block title %}User CEID Association{% endblock %}
{% block content %}
<form novalidate method="post" action="{% url 'pages_admin_set_ceid_user_association' %}" >
{% csrf_token %} {{ form|crispy }}
<input type="submit" class="btn btn-success" value="Update" /><a
href="{% url 'pages_home_page' %}"
><button type="button" class="btn btn-primary">Go Back</button></a
>
</form>
<script>
$('#id_representative').select2({
ajax: {
url: '{% url 'pages_admin_set_ceid_user_association' %}',
dataType: 'json',
data: function(params) {
return {
q: params.term,
term: params.term,
_type: params._type,
dat_type: 'representatives'
}
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
return {id: item.id, text: item.username + ' (' + item.first_name + ' ' + item.last_name + ')'};
})
};
}
},
minimumInputLength: 3
});
$('#id_ceid').select2({
ajax: {
url: '{% url 'pages_admin_set_ceid_user_association' %}',
dataType: 'json',
data: function(params) {
return {
q: params.term,
term: params.term,
_type: params._type,
dat_type: 'ceids'
}
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
console.log(item)
return {id: item.id, text: item.process + ' ' + item.ceid};
})
};
}
},
minimumInputLength: 3
});
</script>
{% endblock content %}
当我尝试提交时,出现以下错误:
枚举是:
PROCESS_LEVELS = [('1270', '1270'), ('1272', '1272'), ('1274', '1274'), ('1222', '1222')]
我已经尝试为 forms.MultipleChoiceField 设置选项,但这并没有解决问题。我试过将字段切换为 CharField 和 ChoiceField,但这也没有解决问题。我也尝试过在表单中删除和添加 novalidate,但这没有任何作用。任何帮助将不胜感激!
找到解决问题的方法: 在我的表单中,我创建了一个自定义多项选择字段:
class CustomMultipleChoiceField(forms.MultipleChoiceField):
"""This field is a MultipleChoiceField designed to override the validation method of a default MultipleChoiceField
"""
def validate(self, value):
return value
这绕过了常规的表单验证程序。然后我将该自定义字段设置为我表单中的字段,并将其从 ModelForm 转换为常规表单:
class PagesAdminSetCeidUserAssociationForm(forms.Form):
representative = CustomMultipleChoiceField(label='WHST Representative')
ceid = CustomMultipleChoiceField(label='CEID')
class Meta:
model = CEID
fields = ['representative', 'ceid']
def __init__(self, *args, **kwargs):
super(PagesAdminSetCeidUserAssociationForm,
self).__init__(*args, **kwargs)
# self.fields['representative'].queryset = get_user_model().objects.none()
# self.fields['ceid'].queryset = CEID.objects.none()
for field in self.fields:
self.fields[field].widget.attrs = {'class': 'form-control'}
if 'ceid' in self.data:
ceid = self.data.get('ceid')
self.fields['ceid'].queryset = CEID.objects.filter(
ceid__in=ceid).order_by()
if 'representative' in self.data:
rep = self.data.get('representative')
self.fields['representative'].queryset = get_user_model(
).objects.filter(username__in=rep)
之后,编写我的 post 请求以按每个输入的 ID 进行过滤是一件简单的事情:
class PagesAdminSetCeidUserAssociation(LoginRequiredMixin, View, UserPassesTestMixin):
template_name = 'pages/pages_admin_set_ceid_user_association.html'
login_url = '/login/'
def test_func(self):
return self.request.user.is_superuser
def get(self, request):
form = PagesAdminSetCeidUserAssociationForm()
if request.is_ajax():
if request.GET.get('dat_type') == 'representatives':
representatives = get_user_model().objects.filter(
username__icontains=request.GET.get('term')
)
representative_response_content = list(
representatives.values())
return JsonResponse(representative_response_content, safe=False)
elif request.GET.get('dat_type') == 'ceids':
ceids = CEID.objects.filter(
ceid__icontains=request.GET.get('term')
)
ceid_response_content = list(ceids.values())
return JsonResponse(ceid_response_content, safe=False)
elif request.GET.get('dat_type') == 'user-ceid-association-container':
representative = get_user_model().objects.get(id=request.GET.get('term[]'))
ceids = list(CEID.objects.filter(representative=representative))
print(ceids)
ceid_name_list = []
for ceid in ceids:
ceid_name_list.append(ceid.__str__())
print(ceid_name_list)
response = {
'representative': representative.username + ' ( ' + representative.first_name + ' ' + representative.last_name + ' )',
'ceids': ceid_name_list,
}
return JsonResponse(response, safe=False)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = PagesAdminSetCeidUserAssociationForm(request.POST or None)
if form.is_valid():
for ceid in CEID.objects.filter(id__in=form.cleaned_data['ceid']):
ceid.representative.set(get_user_model().objects.filter(id__in=form.cleaned_data['representative']))
return render(request, self.template_name, {'form': form})
还有我的 html 代码:
{% extends 'base.html' %} {% load crispy_forms_tags %} {% block title %}User
CEID Association{% endblock %} {% block content %}
<h3>Please note, submitting associate will reset assignment of CEIDs</h3>
<form method="post" action="{% url 'pages_admin_set_ceid_user_association' %}">
{% csrf_token %} {{ form|crispy }}
<input type="submit" class="btn btn-success" value="Update" /><a
href="{% url 'pages_home_page' %}"
><button type="button" class="btn btn-primary">Go Back</button></a
>
</form>
<div
id="user-ceid-association-container"
class="container"
style="display: none"
>
<div class="card mb-4 shadow-sm">
<div class="card-body">
<h6 class="card-text" id="User"></h6>
<ul class="card-text" id="ceids"></ul>
</div>
</div>
</div>
<script>
$('#id_representative').select2({
ajax: {
url: '{% url 'pages_admin_set_ceid_user_association' %}',
dataType: 'json',
data: function(params) {
return {
q: params.term,
term: params.term,
_type: params._type,
dat_type: 'representatives'
}
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
return {id: item.id, text: item.username + ' (' + item.first_name + ' ' + item.last_name + ')'};
})
};
}
},
minimumInputLength: 3
});
$('#id_representative').change(function () {
let representative_value = $(this).val();
$.ajax({
url: '{% url 'pages_admin_set_ceid_user_association' %}',
data: {
'term': representative_value,
'dat_type': 'user-ceid-association-container',
},
success: function(result) {
$('#user-ceid-association-container').css('display', 'block');
$('#User').text(result.representative);
$('#ceids').empty();
if (result.ceids.length > 0) {
for(let i=0; i < result.ceids.length; i++) {
$('#ceids').append('<li class="card-text">' + result.ceids[i] + '</li>');
}}
else {
$('#ceids').append('<li class="card-text">This user has no CEIDs associated to them</li>');
}
return
},
});
});
$('#id_ceid').select2({
ajax: {
url: '{% url 'pages_admin_set_ceid_user_association' %}',
dataType: 'json',
data: function(params) {
return {
q: params.term,
term: params.term,
_type: params._type,
dat_type: 'ceids'
}
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
console.log(item)
return {id: item.id, text: item.process + ' ' + item.ceid};
})
};
}
},
minimumInputLength: 3
});
</script>
{% endblock content %}
这似乎已经成功了!