问题
In my django formset
, I am trying to display a foreign key
field with an input
instead of a select
:
class MinAttend(models.Model):
act = models.ForeignKey(Act)
country = models.ForeignKey(Country)
verbatim = models.ForeignKey(Verbatim)
def __unicode__(self):
return u"%s" % self.verbatim
class MinAttendForm(forms.ModelForm):
country=forms.ModelChoiceField(queryset=Country.objects.all(), empty_label="Select a country")
status=forms.ModelChoiceField(queryset=Status.objects.values_list('status', flat = True).distinct(), empty_label="Select a status")
verbatim=forms.CharField(max_length=300)
class Meta:
model=MinAttend
#fields used for the validation and order
fields = ('country', 'status', 'verbatim')
For the verbatim field, I do have an input box instead of a select but when I want to update a formset, I have the verbatim id instead of its corresponding text:
Here is how I initialize the form:
class MinAttendUpdate(UpdateView):
object=None
model = MinAttend
form_class=MinAttendForm
nb_extra_forms=3
def post(self, request, *args, **kwargs):
attendances=MinAttend.objects.filter(...)
#set the number of forms to the number of ministers + 3 extra form to fill if needed
MinAttendFormSet = modelformset_factory(self.model, form=self.form_class, extra=len(attendances), max_num=len(attendances)+self.nb_extra_forms, can_delete=True)
formset=MinAttendFormSet(queryset=attendances)
I have tried two things:
Instead of the last line I have the following code:
initials=[]
#display text of verbatim instead of id
for index in range(len(attendances)):
initials.append({"verbatim": attendances[index].verbatim.verbatim})
print "initials", initials
formset=MinAttendFormSet(queryset=attendances, initial=initials)
I have overridden the init
method of the form:
#~ #verbatim text instead of id for the verbatim field
def __init__(self, *args, **kwargs):
super(MinAttendForm, self).__init__(*args, **kwargs)
instance = kwargs.get("instance", None)
if instance!=None:
print "instance", instance.verbatim.verbatim
self.fields["verbatim"].initial = instance.verbatim.verbatim
None of these methods works, I still get numbers instead of text! What is curious is that I do see text for the verbatim field but only for the three extra forms. Normal?
EDIT - from Bernd Jerzyna comment
In my form:
from django.forms.models import BaseModelFormSet
class MinAttendFormSet(BaseModelFormSet):
def __init__(self, *args, **kwargs):
super(MinAttendFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
#skip extra forms
if not form.empty_permitted:
form.fields['verbatim'].initial= form.instance.verbatim
print "verbatim MinAttendFormSet", form.instance.verbatim
In my view:
from forms import MinAttendForm, MinAttendFormSet
my_formset = modelformset_factory(self.model, form=self.form_class, formset=MinAttendFormSet)
formset = my_formset(request.POST, queryset=attendances)
When I do a print of the text of each verbatim, I see the correct text displayed. However, I still see numbers (primary key ids) in the form of my web page ;(.
What's wrong?
回答1:
I think something like this should work:
Implement the init method of your formset like
def __init__(self, *args, **kwargs):
...
super(MinAttendFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
form.fields['verbatim'].initial= form.instance.verbatim
That would also require your Verbatim model to have something like:
def __unicode__(self):
return u'%s' % (self.name)
回答2:
This is my understanding of it...
As a select widget, the verbatim is displayed with the __unicode__
results, but the value 'behind the scenes' is the PK/verbatim-id, ie the HTML <option>
tag has a value and 'label'. When you change it to a text input widget, it is expecting you to enter the PK, hence why you are seeing the numbers.
For the solution, I am not sure. You could write some code to accept the verbatim-text, rather than the pk/verbatim-id. The problem with this though, is that if the text is not written exactly, django won't find a match. Also, if more than 1 verbatim has the same text, django wouldn't know which one to use (unless you have set unique=true on the model field for text). You could also set the verbatim-text as the PK.
Perhaps using something like Django-Select2 will give you the desired UI?
来源:https://stackoverflow.com/questions/24608756/formset-and-input-text-for-each-foreign-key