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) {
}
});
Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.
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.
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.
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.
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) {
}
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With