Issue
I am working on a Django project that connects dogs with behavioral issues with people who can help the owner overcome those issues. Most of the project has been translated, but there are a few strings that aren't being translated.
Here is the relevant model:
from django.utils.translation import ugettext_lazy as _
class Issue(models.Model):
PEOPLE = 'PE'
OWNERS = 'OW'
EXPERIENCED_PEOPLE = 'EX'
HELPER_CHOICES = ((PEOPLE, _('People')),
(OWNERS, _('Owners')),
(EXPERIENCED_PEOPLE, _('People with experience')))
who_can_help = models.CharField(_('Who can help?'),
blank=False,
choices=HELPER_CHOICES,
default=PEOPLE,
max_length=2,
null=False)
doggo = models.ForeignKey(Doggo, on_delete=models.CASCADE)
and the relevant bit in forms.py
IssueFormSet = modelformset_factory(Issue, fields=['title', 'description', 'plan', 'who_can_help'])
Finally, the view (I've left out the part for dealing with POST requests):
def doggo_create_view(request):
doggo_form = DoggoForm()
issue_formset = IssueFormSet(queryset=Issue.objects.none())
return render(request, 'doggos/doggo_form.html', {'form': doggo_form, 'formset': issue_formset})
Instead of "People", it should say "Mensen" (as in the .po file, which I haven't forgotten to compile). Any ideas?
Solution
I found a way to make it work. To be quite truthful, I don't understand every aspect of what's going on here, but I puzzled it together from related issues.
The workaround seems to be to create an explicit modelform and to use a lazy version of ChoiceField. I found code for the latter here. Here's my forms.py:
class LazyChoiceField(ChoiceField):
'''
A Lazy ChoiceField.
This ChoiceField does not unwind choices until a deepcopy is called on it.
This allows for dynamic choices generation every time an instance of a Form is created.
'''
def __init__(self, *args, **kwargs):
# remove choices from kwargs.
# choices should be an iterable
self._lazy_choices = kwargs.pop('choices',())
super(LazyChoiceField,self).__init__(*args, **kwargs)
def __deepcopy__(self, memo):
result = super(LazyChoiceField,self).__deepcopy__(memo)
lz = self._lazy_choices
if callable(lz):
lz = lz()
result.choices = lz
return result
class IssueForm(forms.ModelForm):
who_can_help = LazyChoiceField(choices=((PEOPLE, _('People')),
(OWNERS, _('Owners')),
(EXPERIENCED_PEOPLE, _('People with experience'))))
class Meta:
model = Issue
fields = ['title', 'description', 'plan']
I got the idea from this similar issue.
It's not that I don't have any clue why this works, but it's not as sharp in my mind as it could be yet, so if anyone has any further insights about why this is needed and why it works, they are still welcome.
Answered By - VforVincent
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.