How to get variable value from html into views.py in django - django

html code:
{% for data in top_100_active_webshells_tuple %}
<tr>
<td>{{ data.0 }}</td>
<td>{{ data.1 }}</td>
<td>{{ data.2 }}</td>
<td><form action="/my_image/" method="POST">
{% csrf_token %}
<input id ="my_input" type="submit" class="btn" name="{{ data.3 }}" value="image" style="background:white;color:black;border:3px solid grey"/>
</form>
</td>
</tr>
{% endfor %}
views.py function:
def my_image(request):
if "data.3" in request.GET:
address=request.GET["data.3"]
resp="address is "+address
return HttpResponse(resp)
else:
return HttpResponse("error here")
Question:
Question is that i can't get value stored in variable "data.3 "in the function named
def my_image(request)
And else statement is printed when i click input button,how to fix it and get variable value in views.py
Please reply as soon as possible.

You will get the value of data.3 and not data.3 as a key in the request data.
Also, you will receive the data in request.POST and not request.GET as form method is POST.
def my_image(request):
if <value_of_data.3> in request.POST:
address=request.POST[<value_of_data.3>]
resp="address is "+address
return HttpResponse(resp)
else:
return HttpResponse("error here")
But, as you are iterating and the value of data.3 might change in different requests, you won't be able to get your view to work correctly everytime as intended using the above logic.

Related

Form in a dynamic HTML table

I am trying to create a HTML table, with a 2 fields on each row for the user to fill in (sports matches predictions). It loads data from one table(List) and should write into another one (Predictions)
Right now I have a cycle which loops through the matches and based on that creates the HTML table.
input.html
{% block body %}
<form method="post">
{% csrf_token %}
<table class="table">
<tr>
<th>Round</th>
<th>Date</th>
<th>Time</th>
<th>Home</th>
<th class="col-md-1"></th>
<th class="col-md-1"></th>
<th class="col-md-1"></th>
<th>Away</th>
</tr>
{% for item in query_results %}
<tr>
<td>{{ item.match_round }}</td>
<td>{{ item.match_date }}</td>
<td>{{ item.match_time }}</td>
<td>{{ item.home_team_name }}</td>
<td>{{ form.home_goals_predictions|add_class:"form-control"}}</td>
<td class="text-center">:</td>
<td>{{ form.away_goals_predictions|add_class:"form-control"}}</td>
<td>{{ item.away_team_name }}</td>
</tr>
{% endfor %}
</table>
<button type="submit" class="btn btn-success">Submit</button>
</form>
{% endblock %}
This is works and displays the table excatly as I want.
However I am not able to extract the data as I want from it - to be more exact, when submiting the form, the data from the last row gets assigned to all the rows.
views.py
query_results = List.objects.all()
form = PredictionsForm()
if request.method == 'POST':
form = PredictionsForm(request.POST)
if form.is_valid():
user_prediction = form.save(commit = False)
for result in query_results.all():
for home_goals_predictions, away_goals_predictions in form.cleaned_data.items():
user_prediction.id = result.id
user_prediction.match_round = result.match_round
user_prediction.home_team_name = result.home_team_name
user_prediction.away_team_name = result.away_team_name
user_prediction.user_id = request.user.id
user_prediction.home_goals_predictions = form.cleaned_data['home_goals_predictions']
user_prediction.away_goals_predictions = form.cleaned_data['away_goals_predictions']
user_prediction.save()
return redirect('/matches/')
else:
return redirect('/matches/')
else:
template = loader.get_template('matches/input.html')
context = {
'query_results': query_results,
'form': form
}
return HttpResponse(template.render(context, request))
forms.py
class PredictionsForm(forms.ModelForm):
home_goals_predictions = forms.IntegerField(widget=forms.Textarea(attrs={'cols': 1, 'rows': 1, 'maxlength': '2'}))
away_goals_predictions = forms.IntegerField(widget=forms.Textarea(attrs={'cols': 1, 'rows': 1, 'maxlength': '2'}))
class Meta:
model = Predictions
fields = ('home_goals_predictions', 'away_goals_predictions')
I would really appreciate the help, as I am stuck on this problem and cannot figure out correct solution using formset/for loop.
I'm not entirely sure what's going on in your code since I can't see the definition of query_results but I'm pretty sure that what you are looking for is formsets. In short, a form submit's one thing / record. A formset is as the name suggest a set of forms, see the documentation for a full example. Also take a look at modelformsets, depending on your usecase this might really come in handy as well.
Edit:
Yeah so I would definitely go the modelformset route. Here's a short example of what that would like
in your views.py (the GET request).
from django.forms import modelformset_factory
ListFormSet = modelformset_factory(List, form=ListForm, extra=0)
list_formset = ListFormSet(queryset=List.objects.all())
Then during POST you can just do
ListFormSet = modelformset_factory(List, form=ListForm, extra=0)
list_formset = ListFormSet(request.POST, queryset=List.objects.all())
if list_formset.is_valid():
for list_form in list_formset:
list_form.save()
analogue to how a normal single form works.
Then in your template
<form enctype="multipart/form-data" method="post">
{{ list_formset.management_form }}
{% for list_form in list_formset %}
...
{{ list_form.instance.match_round }}
...
{{ list_form.home_goals_predictions }} #formfield
{{ list_form.away_goals_predictions }} #formfield
{% endfor %}
</form>
As you can see it is possible to access the query data via .instance
note: I typed this from memory so you might have to debug some typo's.

i want to display only selected year data in Django

Here i put my code file so you can get idea about my code
In my index.html
{% load tag %}
<body>
<select name="select_year">
<option>2017</option>
<option>2018</option>
<option>2019</option>
<option>2020</option>
</select>
</br>
</br>
<table border="1">
<tr>
<td>No</td>
<td>Name</td>
<td>DOB</td>
<td>Year</td>
</tr>
{% for Manvi_User in ordering %}
<tr>
<td>{{forloop.counter}}</td>
<td>{{ Manvi_User.first_name }}</td>
<td>{{ Manvi_User.dob}}</td>
<td>{{year|calculate_year:forloop.counter0}}</td>
</tr>
{% endfor %}
</table>
</body>
in vies.py
def index(request):
all_user = Manvi_User.objects.all()
ordering = all_user.order_by('dob')
return render(request, 'index.html', {'ordering': ordering})
in tag.py
#register.filter
def calculate_year(year, loop_counter):
try:
year = int(2017)
except ValueError:
return None
else:
return str(year + (loop_counter // 2))
in year i put static year using tag.py
if user select 2019 i want to display only data who have year 2019
As far as I understand what you're trying to do here, which is to filter the queryset depending on the year selected - the way you started is not really the way to do it.
You should look into django-filter app which makes it pretty easy to accomplish what you're trying here.
For this specific situation, you'd have to define your custom filter within filters.py, and then use that filter in your view.

Django, I want to take an input from a form and contents of the template should be according to the input

models.py
class Transaction(models.Model):
created_date = models.DateField('created_date')
price = models.IntegerField(default=0)
abc = models.IntegerField(default=0)
pqr = models.IntegerField(default=0)
ghi = models.IntegerField(default=0)
Then I take a user input
input.html
<form method="POST" action="search/" style="margin-left:5em;">
{% csrf_token %}
<input type="radio" name="account" value="price"> price<br>
<input type="radio" name="account" value="abc"> abc<br>
<input type="radio" name="account" value="pqr"> pqr<br>
<input type="radio" name="account" value="ghi"> ghi<br>
</form>
views. py
def search(request):
if request.method == 'POST':
search_id = request.POST.get("account", None)
selected_transactions = Transaction.objects.exclude(search_id=0)
return render(request, 'stats/account_details.html', {'selected_transactions': selected_transactions,
'search_id': search_id})
else:
return render(request, 'stats/index.html')
I have to display contents based on user input.
account_details.html
<table>
<tr>
<th>Transaction date</th>
<th>{{ search_id }}</th>
</tr>
{% for transaction in selected_transactions %}
<tr>
<td>{{ transaction.created_date }}</td>
<td>{{ transaction.{{ search_id }} }}</td>
</tr>
{% endfor %}
</table>
I have two issues here.
1.Transaction.objects.exclude(search_id=0) doesn't work. It does not take the value of variable search_id. How do I exclude dynamically those transactions where user input attribute=0?
2.{{ transaction.{{ search_id }} }} in account_details.html doesn't work as it is a syntax error. I need to display data varying on user input. How do I use two variables inside a single tag in my template?
I get that I can resolve both using if else statements, but I have a large no. of attributes. So, is there a shorter way to do it?
Any help is appreciated.
Issue 1: You are trying to use an attribute in a query set filter which is not present in your model. You might want to use any of your attributes of your model like price or any other attribute.
Issue 2: Code below:
<td>{{ transaction.created_date }}</td>
<td>{{ transaction.{{ search_id }} }}</td>
is not correct for various reasons. First thing that you are trying to access created_date attribute which is not present in your queryset attribute. Either you have to remove this attribute or add it into your model. Your second line is incorrect because its a syntax error. Below one might be helpful to you and its syntactically correct.
<td> {{ search_id }} </td>
Edit: You can put if else to compare which search_id is selected by the user and based on that corresponding data can be displayed.
{% if search_id == "abc" %}
{{ transaction.abc }}
{% elif search_id == "pqr" %}
{{ transaction.pqr }}
{% endif %}

Passing data back to Django view

Inside of a table in my template I have the following which works great:
<tbody>
{% for item in items %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.status }}</td>
<td>{{ item.start_time }}</td>
<td>{{ item.end_time }}</td>
</tr>
</tbody>
I would like to add a form that posts the items to a view. I've tried this:
<form align="center" action="{% url 'app:doit' %}" method="post" ><b></b>
{% csrf_token %}
<input type="hidden" name="items" value="{{ items}}" />
<input type="submit" name="export" value="Export" >
</form>
but that doesn't work as I expected it would. The data comes into the view as a sequence of characters, something like this, ",..." How do I pass {{items}} back to a view so I can process the items as python objects?
The export method in my view contains this:
if 'items' in request.POST:
my_items = request.POST['items']
You cannot POST a QuerSet back to a view. HTML form cannot understand a Django QuerySet. That would be nice, though!
What you can do is to create a custom template tag that would generate this:
<input type="hidden" name="items" value="{% my_items items %}" />
to this:
<input type="hidden" name="items" value="1,2,5,7,8" />
where these numbers are the id of each item. You can also use the name field if you like, since it's not very secure to expose the ids.
Then, once POSTed, inside the view I would do:
if 'items' in request.POST:
# my_item_values is a str
my_item_values = request.POST['items']
try:
my_item_values = my_item_values.split(',')
except TypeError:
# Handle error of conversion from string to list here
else:
# typecast succedded. Get your items!
items = Item.objects.filter(id__in=my_item_values) # This is a QuerySet
# or this (if you used the names)
items = Item.objects.filter(name__in=my_item_values) # This is a QuerySet
The custom template tag would look like this:
#register.simple_tag()
def my_items(items):
return ','.join([item.name for item in items])

How do I set value to hidden integerfield in WTForms

I have a form which needs to take in 1 integer value. This integer value will be an id associated with a row in a html table.
template.html
{% block content %}
<div id="formContainer" class="center top">
<p class="lead">Select simulation session </p>
{% if simulationSessions %}
<table class="table table-striped">
<thead>
<tr>
<th></th>
<th>#</th>
<th>Label</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{% for simulationSession in simulationSessions %}
<tr>
<td><input id="id-{{ simulationSession.id }}" name="idRadio" type="radio" value="{{ simulationSession.id }}"> </td>
<td>{{ simulationSession.id }}</td>
<td>{{ simulationSession.label }}</td>
<td>{{ simulationSession.date.strftime('%d-%m-%y %H:%M') }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="button" class="btn btn-sm btn-success">Analyse</button>
{% else %}
<div class="alert alert-danger" role="alert">
<strong>Oopsadazy!</strong> No simulations are registered in the database for this user. You need to run a simulation session before analyzing it!
</div>
{% endif %}
</div>
{% endblock %}
Each table row has a radio button, and the value from the selected button will be the only thing my form requires. I have decided to go with one hidden IntegerField instead of a RadioField. It is possible to do the latter but then I have to solve the problem of dynamically creating the choices (I decided to go against that when I couldn't pass the list as a parameter when referencing the form from my view.py).
form.py
class SimulationSessionSelectionForm(Form):
simulationSessoinId = IntegerField('simulationSessoinId', validators=[DataRequired()], widget=HiddenInput())
My questions is how can I take the value from the selected radio button and use that as the data for the hidden integer field once the form is submitted?
This could maybe be done with something similar to this inside a script within the html? (this does not compile)
{% set form.id.data %}
this.value
{% endset %}
The view would look something like this:
view.py
#app.route('/dashboard', methods=['GET', 'POST'])
#login_required
def dashboard():
form = SimulationSessionSelectionForm()
if form.validate_on_submit():
redirect('/somewhere')
userkey = models.User.query.filter_by(id = current_user.get_id()).first().userKey
userSimulationSessions = models.SimulationSession.query.filter_by(userKey = userkey).all()
simulationSessions = []
simulationSessionIds = []
for simulation in userSimulationSessions:
simulationSessions.append({'id' : simulation.sessionID, 'label' : simulation.label, 'date' : simulation.date})
simulationSessionIds.append(simulation.sessionID)
return render_template("dashboard.html", simulationSessions = simulationSessions, form = form)
This line in the template adds the hidden field (and the csfr token) to the
{{ form.hidden_tag() }}
I figured I could just set the value of the hidden IntegerField by some jquery script whenever the radio button change event fired. To do this I used the following code:
<script>
$( document ).ready(function() {
$('input[type=radio][name=idRadio]').change(function() {
$('#simulationSessoinId').val(this.value)
});
});
</script>