Hello.

I want to let users to choose their countries. I have 2 models = *Countries* 
with some figures and *CountriesTranslations*. I am trying to make tuple 
with *country* (because user has FK to this model) and its *translation*. 
In front-end I see dropdown list of countries, but when I try to save the 
form, I see error: *Exception Value: Cannot assign "'AF'": 
"UserProfile.country" must be a "Countries" instance.* Error happens at the 
line *if user_profile_form.is_valid():*

# admindivisions.models
class Countries(models.Model):
    osm_id = models.IntegerField(db_index=True, null=True)
    status = models.IntegerField()
    population = models.IntegerField(null=True)

    iso3166_1 = models.CharField(max_length=2, blank=True)
    iso3166_1_a2 = models.CharField(max_length=2, blank=True)
    iso3166_1_a3 = models.CharField(max_length=3, blank=True)

    class Meta:
        db_table = 'admindivisions_countries'
        verbose_name = 'Country'
        verbose_name_plural = 'Countries'


class CountriesTranslations(models.Model):
    common_name = models.CharField(max_length=81, blank=True, db_index=True)
    formal_name = models.CharField(max_length=100, blank=True)

    country = models.ForeignKey(Countries, on_delete=models.CASCADE, 
verbose_name='Details of Country')
    lang_group = models.ForeignKey(LanguagesGroups, on_delete=models.CASCADE
, verbose_name='Language of Country',
                                   null=True)

    class Meta:
        db_table = 'admindivisions_countries_translations'
        verbose_name = 'Country Translation'
        verbose_name_plural = 'Countries Translations'


# profiles.forms
class UserProfileForm(forms.ModelForm):

    # PREPARE CHOICES
    country_choices = ()
    lang_group = Languages.objects.get(iso_code='en').group
    for country in Countries.objects.filter(status=1):
        eng_name = country.countriestranslations_set.filter(lang_group=
lang_group).first()
        if eng_name:
            country_choices += ((country, eng_name.common_name),)
    country_choices = sorted(country_choices, key=lambda tup: tup[1])


    country = forms.ChoiceField(choices=country_choices, required=False)

    class Meta:
        model = UserProfile()
        fields = ('email', 'email_privacy',
                  'profile_url',
                  'first_name', 'last_name',
                  'country',)


# profiles.views
def profile_settings(request):
    if request.method == 'POST':
        user_profile_form = UserProfileForm(request.POST, instance=request.
user)

        if user_profile_form.is_valid():
            user_profile_form.save()
            messages.success(request, _('Your profile was successfully 
updated!'))

            return redirect('settings')

        else:
            messages.error(request, _('Please correct the error below.'))

    else:
        user_profile_form = UserProfileForm(instance=request.user)

    return render(request, 'profiles/profiles_settings.html', {
        'user_profile_form': user_profile_form,
    })

As I understand, *country* from *((country, eng_name.common_name),)* is 
converted to *str*. What is the right way to keep country instance in the 
form? or if I am doing it in the wrong way, what way is correct?

As a possible solution is to use *ModelChoiceField* with overriding 
*label_from_instance* as shown below:
class CountriesChoiceField(forms.ModelChoiceField):
    def __init__(self, user_lang='en', *args, **kwargs):
        super(CountriesChoiceField, self).__init__(*args, **kwargs)
        self.user_lang = user_lang

    def label_from_instance(self, obj):
        return obj.countriestranslations_set.get(lang_group=self.user_lang)


class UserProfileForm(forms.ModelForm):
user_lang = user_lang_here
country = CountriesChoiceField(
    queryset=Countries.objects.filter(
        status=1, iso3166_1__isnull=False,
        countriestranslations__lang_group=user_lang).order_by(
'countriestranslations__common_name'),
    widget=forms.Select(), user_lang=user_lang)

    class Meta:
        model = UserProfile()
        fields = ('email', 'email_privacy',
                  'profile_url',
                  'first_name', 'last_name',
                  'country',)

but in this case there are too much queries because of the 
*label_from_instance* and page loads too slowly.
Would appreciate any advice how to solve this task.
Thanks.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/b2b0e010-f549-4225-93a3-ee42249a6120%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to