Randy Tang
Randy Tang

Reputation: 4353

Editing the queryset of django models

I have the following model and form:

# Model
class Fruit(...):
    name = models.CharField(...)       # Default name of the fruit
    engName = models.CharField(...)    # English name

    def __str__(self):
        return self.name


# Form
class ComboProductForm(forms.ModelForm):
    fruit =  forms.ModelChoiceField(queryset=Fruit.objects.none())

    def __init__(self, *args, **kwargs):
        branch = kwargs.pop('branch')
        fruits = Fruit.objects.filter(branch=branch)    # Branch of the company
        self.fields['fruit'].queryset = fruits

Every branch in the company has different fruits, so I have to filter the fruits in the __init__ method. What I want is to modify the queryset according to the request.LANGUAGE_CODE:

    def __init__(self, *args, **kwargs):
        branch = kwargs.pop('branch')
        language = kwargs.pop('language')
        fruits = Fruit.objects.filter(branch=branch)    # Branch of the company
        if language == 'en':
            for fruit in fruits:
                fruit.name = fruit.engName
        self.fields['fruit'].queryset = fruits

That is, display English fruit names if the language code is English. However, the contents of the resulting fruits seem not changed. How do I do to modify the queryset?

I have also tried the following:

fruits = list(fruits)
for fruit in fruits:
    fruit.name = fruit.engName

But then I have to convert fruits back to queryset type. How do I do that and will this work?

I am also thinking about returning different fields in the model method __str__:

def __str__(self):
    if language_code == 'English':    # Hypothetical statement
        return self.name
    return self.engName

But have no clue how to do that. Please help and thanks.

Upvotes: 0

Views: 429

Answers (2)

Randy Tang
Randy Tang

Reputation: 4353

Inspired by Raj, I came up with the following solution:

def __init__(self, *args, **kwargs):
    branch = kwargs.pop('branch')
    language = kwargs.pop('language')
    fruits = Fruit.objects.filter(branch=branch)    # Branch of the company
    self.fields['fruit'].queryset = fruits
    if language == 'en':
        self.fields['fruit'].label_from_instance = lambda obj: "%s" % obj.engName

Upvotes: 1

Raj Subit
Raj Subit

Reputation: 1557

Try this:

class ComboProductForm(forms.ModelForm):
    fruit =  forms.ModelChoiceField(queryset=Fruit.objects.none())

    def __init__(self, *args, **kwargs):
        branch = kwargs.pop('branch')
        language = kwargs.pop('language')
        fruits = Fruit.objects.filter(branch=branch)    # Branch of the company
        self.fields['fruit'].queryset = fruits
        self.fields['fruit'].label_from_instance = self.label_from_instance(language)

    @staticmethod
    def label_from_instance(obj, language):
        if language == 'en':
            return obj.engName
        return obj.name

Upvotes: 1

Related Questions