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 django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
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