Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: How to change form field select options with different Querysets, based on other form field options selected?

Tags:

I want the queryset of my coin field to change when a user selects "Sell" in the "BuySell" dropdown option with jquery. Once the dropdown is changed I send a Get Request with AJAX, pick that request up in my view and then reload the form, which is where I override the default coin field queryset in my TransactionForm's init method.

This isn't working as expected, nothing happens to change the coin dropdown options and I get no errors (including in the Network tab when I inspect element).

I wonder if this is something to do with the way I'm calling my form here:

form = TransactionForm(user = request.user, coin_price = GetCoin("Bitcoin").price)

and the form init method:

def __init__(self, coin_price = None, user = None, *args, **kwargs):    
        super(TransactionForm, self).__init__(*args, **kwargs)

        if user:

            self.user = user
            qs_coin = Portfolio.objects.filter(user = self.user).values('coin').distinct()
            print("qs_coin test: {}".format(qs_coin))
            self.fields['coin'].queryset = qs_coin

FULL CODE:

Forms

class TransactionForm(forms.ModelForm):     
    CHOICES = (('Buy', 'Buy'), ('Sell', 'Sell'),)

    coin = forms.ModelChoiceField(queryset = Coin.objects.all()) 
    buysell = forms.ChoiceField(choices = CHOICES)

    field_order = ['buysell', 'coin', 'amount', 'trade_price']

    class Meta:
        model = Transaction
        fields = {'buysell', 'coin', 'amount', 'trade_price'}

    def __init__(self, coin_price = None, user = None, *args, **kwargs):
        super(TransactionForm, self).__init__(*args, **kwargs)
        print("Transaction form init: ", user, coin_price)

        if user:
            self.user = user
            qs_coin = Portfolio.objects.filter(user = self.user).values('coin').distinct()
            print("qs_coin test: {}".format(qs_coin))
            self.fields['coin'].queryset = qs_coin

Views snippet

def add_transaction(request):

    if request.method == "GET":
        if request.is_ajax():
            print("ajax test")

            #print(request.GET.get)
            print(request.GET.get('coin'))
            print(request.GET.get('buysell'))

            view_coin = None 
            if request.GET.get('coin'):
                view_coin = GetCoin(request.GET.get('coin')).price

            data = {
                'view_buysell': request.GET.get('buysell'),
                'view_coin': request.GET.get('coin'),
                'view_amount': "test",
                'view_price': view_coin
            }

            form = TransactionForm(user = request.user, coin_price = GetCoin("Bitcoin").price)

            return JsonResponse(data)

jquery

$('#id_buysell').on('change', function(){

        console.log("buysell");

        var $id_buysell = $('#id_buysell').val();
        console.log($id_buysell);

        $.ajax({
            method: "GET",
            url: "/myportfolio/add_transaction",
            dataType: 'json',
            data: { buysell: $id_buysell },
            success: function(data, status) {
                console.log("SUCCESS:");
                console.log(data);
                console.log(data['view_buysell']);

            },
            error: function(response) {

            }
        });

    });

$('#id_coin').on('change', function(){

    console.log("test")
    console.log("coin change")

    var $id_coin = $('#id_coin').find("option:selected").text();
    console.log($id_coin);

    $.ajax({
        method: "GET",
        url: "/myportfolio/add_transaction",
        dataType: 'json',
        data: {coin: $id_coin},
        success: function(data, status) {
            console.log("SUCCESS:");
            console.log(data);
            console.log(data['view_buysell']);

            $("#id_trade_price").val(data['view_price']);
        },
        error: function(response) {

        }
    });
like image 223
SkillSet12345 Avatar asked May 29 '18 09:05

SkillSet12345


People also ask

How do you exclude a specific field from a ModelForm?

Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.

How do I make a field optional in Django?

In order to make a field optional, we have to say so explicitly. If we want to make the pub_time field optional, we add blank=True to the model, which tells Django's field validation that pub_time can be empty.

How do you customize a form in Django?

So, we have to just design the HTML with css, and use it in Django by just replacing the input tag with render_field and form. field_name with {% %} at the end and design it with our choice.

What is ModelForm in Django?

Django ModelForm is a class that is used to directly convert a model into a Django form. If you're building a database-driven app, chances are you'll have forms that map closely to Django models. For example, a User Registration model and form would have the same quality and quantity of model fields and form fields.


1 Answers

What I was trying to do was unnecessary.

The correct way to achieve this was to convert all of my querysets into lists and then pass them to jquery in JsonResponse. Then I can clear and load these lists as select options in my jquery as and when I need.

updated code:

views

if request.method == "GET":
        if request.is_ajax():
            print("ajax test")

            #print(request.GET.get)
            print(request.GET.get('coin'))
            print(request.GET.get('buysell'))

            view_coin = None 
            if request.GET.get('coin'):
                view_coin = GetCoin(request.GET.get('coin')).price

            coin_sell_options = Portfolio.objects.filter(user = request.user).values('coin').distinct()
            coin_buy_options = Coin.objects.all()

            coin_buy_options = [x.coin for x in coin_buy_options]

            coins = [key['coin'] for key in coin_sell_options]
            coin_amount = list(Portfolio.objects.filter(user = request.user, coin__in = coins).values_list('amount', flat = True))
            coin_amount = [str(x) for x in coin_amount]
            print(coin_amount)

            data = {
                'view_buysell': request.GET.get('buysell'),
                'view_coin': request.GET.get('coin'),
                'view_amount': "test",
                'view_price': view_coin,
                'coin_sell_options': list(coin_sell_options),
                'coin_buy_options': list(coin_buy_options),
                'coin_amounts': coin_amount
            }

            form = TransactionForm(user = request.user, coin_price = GetCoin("Bitcoin").price)

            return JsonResponse(data)

jquery

$('#id_buysell').on('change', function(){

            console.log("buysell");

            var $id_buysell = $('#id_buysell').val();
            console.log($id_buysell);

            $.ajax({
                method: "GET",
                url: "/myportfolio/add_transaction",
                dataType: 'json',
                data: { buysell: $id_buysell },
                success: function(data, status) {
                    console.log("SUCCESS:");
                    console.log(data);
                    console.log(data['view_buysell']);

                    $("#id_coin").empty();                  

                    var items = data['coin_options'];

                    console.log(items);

                    $.each(items, function(key, value) {
                        console.log(value.coin);
                        $("#id_coin").append(new Option(value.coin));
                    });


                },
                error: function(response) {

                }
            });

        });
like image 89
SkillSet12345 Avatar answered Sep 28 '22 18:09

SkillSet12345