How to retrieve value from checkbox defined in django template - python

I have created a menu with three options(home,change password and logout). In home I am displaying all the books stored in the database. Now I want to filter the contents based on categories of the books using checkbox. By default all the books are shown upon filtering the category only the books of that category should be shown.But for me it is showing all the books even after clicking on all the checkbox (checkbox contains the categories).I think there is some problem in my template file.
urls.py,
url(r'^welcome_user/$',views.welcome_user, name='welcome_user'),
Models.py,
class Add_cat(models.Model):
category = models.CharField("Name",max_length=25,unique=True)
def __unicode__(self):
return u'{0}'.format(self.category)
class Add_prod(models.Model):
book = models.CharField("Book Name",max_length=40)
author = models.CharField("Author",max_length=30)
price = models.PositiveIntegerField("Price")
image = models.ImageField(upload_to='images',null=True)
cat = models.ForeignKey(Add_cat,on_delete=models.CASCADE)
Template file,
{% block content %}
{% load staticfiles %}
<head>
<link rel="stylesheet" href="{% static 'style.css' %}">
</head>
<body>
<div class="box">
<div class="sideNav">
<form action="{% url 'welcome_user' %}">
<p id=id3>Categories</p>
<hr>
{% for i in products %}
<input type="checkbox" name="cat_name" value="{{i.cat}}">{{i.cat}}<br>
{% endfor %}
<button type="submit">Submit</button>
</form>
</div>
<div>
{% for i in products %}
<div style="display:inline-block;margin:30px">
<img src="{{i.image.url}}" alt="No Image" width=196px height=196px>
<p id=id4>Rs.{{i.price}}</p>
</div>
{% endfor %}
</div>
</div>
</body>
{% endblock %}
Views.py,
#login_required
def welcome_user(request):
if 'cat_name' in request.GET:
filter_category = request.GET.getlist('cat_name')
my_products = Add_prod.objects.filter(cat__in=filter_category)
context = { "products":my_products}
else:
my_products = Add_prod.objects.all()
context = { "products":my_products}
return render(request,"welcome-user.html",context)

To check whether checbox value is in sent form you should go with following condition
if 'cat_name' in request.GET:
#checkbox has been checked
else:
#it is not checked
Remember that in operator return boolean so you can also do
filter_category = 'cat_name' in request.GET
To get value you just need to get values of 'cat_name' key like:
value = request.GET['cat_name']
after checking whether it is in GET parameters or not

I think all you need to do is add __in to your filter:
#login_required
def welcome_user(request):
filter_category = request.GET.getlist('cat_name')
categories = Add_cat.objects.all()
if filter_category: # I couldn’t decipher the structure of an `Add_cat`, so I left off the `in` check since it would not work for lists
print filter_category
my_products = Add_prod.objects.filter(cat__in=filter_category) # the template implies that this field is `cat` and not `category`
context = { "products":my_products}
else:
my_products = Add_prod.objects.all()
context = { "products":my_products}
return render(request,"welcome-user.html",context)

Checkboxes work a little bit different from other form inputs, so if you examine a post sent from a form that includes a checkbox,
if the checkbox is checked, your queryset will look like:
the value will be 'on'
So, you have to check
if request.POST.get('cb1')=='on':
"item is selected"
else:
"item is not selected"

Try this below code
Add_prod.objects.filter(cat__in=filter_category)
#login_required
def welcome_user(request):
filter_category = request.GET.getlist('cat_name')
if filter_category:
my_products = Add_prod.objects.filter(cat__in=filter_category)
context = { "products":my_products}
else:
my_products = Add_prod.objects.all()
context = { "products":my_products}
return render(request,"welcome-user.html",context)
Template file
Remove quotes(') from {% url 'welcome_user' %}
<form method='get' action="{% url welcome_user %}">
UPDATE
Add quotes between views.welcome_user
urls.py
url(r'^welcome_user/$','views.welcome_user', name='welcome_user'),

Related

How to subtract from a Django model?

I am trying to add and subtract 1 from the value of a Django model's IntegerField and display it on the webpage, depending on when a button is clicked.
models.py
class User(AbstractUser):
following = models.ManyToManyField("self", related_name="followers", symmetrical=False)
following_num = models.IntegerField(default=0)
In views.py:
To add: following_num = page_visitor.following_num +1
To subtract: following_num = page_visitor.following_num -1
This is displaying in the html where the number should be displaying:
<django.db.models.query_utils.DeferredAttribute object at 0x0000022868D735E0>
entire view:
def username(request, user):
#get user
user = get_object_or_404(User.objects, username=user)
posts = Post.objects.filter(user=user).order_by('-date_and_time')
page_visitor = get_object_or_404(User.objects, username=request.user)
if user == request.user:
followButton = False
else:
followButton = True
if request.method == "POST":
if "follow" in request.POST:
request.user.following.add(user)
following_num = page_visitor.following_num +1
#following_num = F('User.following_num') + 1
elif "unfollow" in request.POST:
request.user.following.remove(user)
following_num = page_visitor.following_num -1
#following_num = F('User.following_num') - 1
followers_num = page_visitor.following_num
following_num = User.following_num
return render(request, "network/username.html",{
"user": user,
"posts": posts,
"followButton": followButton,
"followers": followers_num,
"following": following_num
})
html
{% block body %}
<h1>{{ user }}</h1>
<h4>Followers:{{ followers }}</h4>
<h4>Following:{{ following }}</h4>
<!--follow/unfollow button-->
{% if followButton == True %}
<form action = "{% url 'username' user %}" method = "POST">
{% csrf_token %}
{% if user not in request.user.following.all %}
<input type="submit" value="Follow" name="follow">
{% else %}
<input type="submit" value="Unfollow" name="unfollow">
{% endif %}
</form>
{% endif %}
<!--displays all the posts-->
{% for post in posts %}
<div class = "individual_posts">
<h5 class = "post_user">{{ post.user }}</h5>
<h6 id = "post_itself">{{ post.post }}</h6>
<h6 class = "post_elements">{{ post.date_and_time }}</h6>
<h6 class = "post_elements">{{ post.likes }} Likes</h6>
</div>
{% endfor %}
{% endblock %}
you reference the class (model) and not the object (instance)
following_num = User.following_num
as you alredy passed your user object to the template you can also access the attributes directly
{{user.following_num }} {{request.user.following_num }}
but you better rename the passed user variable to avoid confusion / errors
Get user information in django templates
Without the html that is supposed to display the number I cant tell why it is displaying that, but if you intend to change the following count then you need to call page_visitor.save() after changing a property of page_visitor in order for it to save the new property's value in the database

How to direct a page from a form Django

I am working on a dictionary app, i am allowing a user to enter a word through a form. When the word is entered in the form and a submit button is pressed i want the form to be maintained on the same page however when the user enter the word and presses submit the form disappears leaving only the submit button and the search results
Here is the dictionary/form code
class NameForm(forms.Form):
your_name = forms.CharField(max_length=100, label=False)
the dictionary/view code
def index(request):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
word = form.cleaned_data['your_name']
print(word)
if Dictionary.get_verb(word):
verb = Dictionary.get_verb(word)
else:
verb = False
print(verb)
if Dictionary.get_noun(word):
noun = Dictionary.get_noun(word)
else:
noun = False
print(noun)
synonyms = Dictionary.get_synonyms(word)
print(synonyms)
form = NameForm()
context = {
'verb':verb,
'noun':noun,
'synonyms':synonyms,
}
return render(request,'index.html' ,context)
else:
form = NameForm()
context = {
'form': form,
}
return render(request, 'index.html', context)
and the index.html
form action="" method="post">
{% csrf_token %}
{{form}}
<br>
<input type="submit" value="Submit">
</form>
<hr>
{% if noun %}
<h2>Noun</h2>
{% for noun_word in noun %}
<p>{{noun_word}}</p>
{% endfor %}
{% else %}
<!-- print nothing-->
{% endif %}
<br>
<hr>
{% if verb %}
<h2>Verb</h2>
{% for verb_info in verb %}
<p>{{verb_info}}</p>
{% endfor %}
{% else %}
<!-- print nothing-->
{% endif %}
<h2>Synonyms</h2>
{% if synonyms %}
{% for synonym_info in synonyms %}
<p>{{synonym_info}}</p>
{% endfor %}
{% else %}
<!-- print nothing-->
{% endif %}
I have created a dictionary class to interact with the Dictionary API. But my challenge is how do i go about it so that when the form is submitted it will return the form and the button together with the results below. Thank you!!
you are missing the form in context when the form is valid, that's why it is disappearing.
form = NameForm()
context = {
'verb': verb,
'noun': noun,
'synonyms': synonyms,
'form': form ## missing this (add)
}
return render(request,'index.html' ,context)
You can add render in forms.py or you can set the action in your template
<form class="postForm" action="{% url 'name of your url' %}" method="POST">

How to make a require object available whenever I type something in search bar in django?

I made a search bar but whenever I write something in it, the link shows http://127.0.0.1:8000/?srh=something and I am not understanding why the the specific picture with title is not showing. It is showing me all pics with title but I want only that pic with title which I write as a title in search bar. Which things to add in this code?
index.html
{% load static %}
{% static 'images/fulls' as baseUrl %}
{% static 'images/thumbs' as hiUrl %}
<form class="new" method="GET" action="">
<input type="text" placeholder='Search..' name="srh" value="{{request.GET.srh}}"> <br>
<button type="submit" class="btn btn-danger"> Search </button>
</form>
<div>
{% for dest1 in target1 %}
{% if dest1 %}
<div>
<a href="{{baseUrl}}/{{dest1.img}}">
<img src="{{hiUrl}}/{{dest1.img}}" alt="" />
<h3>{{dest1.title}}</h3>
</a>
</div>
{% endif %}
{%endfor%}
</div>
views.py
def index(request):
query = request.GET.get('srh')
if query:
match = Destination.objects.filter(title__icontains=query)
target1 = a, b= [Destination() for __ in range(2)]
a.img = 'Article.jpg'
b.img = 'Micro Tasks.jpeg'
a.title = 'Article Writing'
b.title = 'Micro Tasks'
context = {
'target1': target1,
}
return render(request, 'index.html', context)
else:
return render(request, 'index.html')
models.py
class Destination(models.Model):
title = models.CharField(max_length=255)
img = models.CharField(max_length=255)
price = models.IntegerField()
i don't understand why you use a and b but i think this will solve the problem
def index(request):
query = request.GET.get('srh')
if query:
match = Destination.objects.get(desc=query)
context = {
'match': match,
}
return render(request, 'index.html', context)
else:
return render(request, 'index.html')
<div>
{ % if match %}
<div>
<a href="{{baseUrl}}/{{match.img}}">
<img src="{{hiUrl}}/{{match.img}}" alt="" />
<h3>{{match.title}}</h3>
</a>
</div>
{% endif %}
</div>

How to hide button/form with django templates?

I want to hide form if user already pushed on the button. I tried to use a bit of JS code, it works well, but after refreshing page, button on form stay valid. It not a huge surprise for me)) I want hide form using Django templates, but it is not so easy as I thought.
my html :
<div class="who_come">
<p>Who come : </p>
{% for u in who_come %}
{%if u.visiter.username != request.user.username %}
<form class="form-inline" role="form" method="post" id="joinToEventForm">
{% csrf_token %}
<p align="left"><b ><button type="submit">I want join</button></b></p></b></p>
</form>
{% endif %}
{% endfor %}
<div id="who_come_links">
{% for u in who_come reversed %}
<p>{{u.visiter.username}}</p>
{% endfor %}
</div>
<script>
$('#joinToEventForm').submit(function() {
$(this).find("button[type='submit']").prop('disabled',true);
});
</script>
<script>
$('#joinToEventForm').on('submit', function(event){
event.preventDefault();
console.log("form submitted!") // sanity check
$.ajax({
type:'POST',
data:{
action: 'joinEvent',
csrfmiddlewaretoken:'{{ csrf_token }}'
},
success : function (data) {
//console.log(data);
var usernames = JSON.parse(data);
var html_str = '';
for (var i=0; i < usernames.length; i++) {
html_str += '<p>' + usernames[i] + '</p>';
}
$('#who_come_links').html(html_str);
}
});
});
</script>
</div>
my model :
class WhoComeOnEvent(models.Model):
visiter = models.ForeignKey(User, related_name='WhoComeOnEvent')
which_event = models.ForeignKey(Topic, related_name='WhoComeOnEvent')
in this place :
<p>Who come : </p>
{% for u in who_come %}
{%if u.visiter.username != request.user.username %}
<form class="form-inline" role="form" method="post" id="joinToEventForm">
{% csrf_token %}
<p align="left"><b ><button type="submit">I want join</button></b></p></b></p>
</form>
{% endif %}
{% endfor %}
i tried to check who already joined to event and if user that do request same that user in database table, then hide form. But this code doesn't work. It hide form no matter if user exist in db table or not. Second part is that has no connection to current event. Suppose django template that hide form in my case will work. It will check only row in table but it will ignore current it event or it different event (not sure, but i'm afraid of it).
my view :
def p(request, pk):
user = request.user
topic = get_object_or_404(Topic, pk=pk)
post = get_object_or_404(Post, pk=pk)
comment = Comments.objects.filter(pk=pk)
who_come = WhoComeOnEvent.objects.filter(which_event=topic.id)
if request.is_ajax() and request.POST.get('action') == 'joinEvent':
who_come_obj = WhoComeOnEvent.objects.create(
visiter=user,
which_event=post.topic
)
visitors_usernames = []
for w in who_come:
visitors_usernames.append(w.visiter.username)
return HttpResponse(json.dumps(visitors_usernames))
if request.method == 'POST':
form = CustomCommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.creator = user
comment = Comments.objects.create(
body=form.cleaned_data.get('body'),
creator=user,
post=post
)
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
# return render(request, 'post.html', {'post': post, 'topic': topic, 'comment': comment,
# 'form': form, 'who_come': who_come})
else:
form = CustomCommentForm()
return render(request, 'post.html', {'post': post, 'topic': topic, 'comment': comment,
'form': form, 'who_come': who_come})
Solution:
I found more elegant solution, just adding .distinct('visitor') to my who_come queryset.
If someone will read it question and found my solution helpful, notice, that objects still creating to the databese and it doesn't unique!

Use two different forms in same template

I am trying to write a condition where if 1st part is ok then 2nd part will show.I wrote my forms.py in a following way :
class SubmissionForm(forms.Form):
first_name=forms.CharField(max_length=120, required=True)
last_name=forms.CharField(max_length=120, required=True)
class UploadForm(forms.Form):
file1 = forms.Field(label='File1', widget = forms.FileInput,required = True )
file2 = forms.Field(label='File1', widget = forms.FileInput, required = True )
In my views.py:
def submission(request):
validform=False
title="Please submit your data"
form = SubmissionForm(request.POST)
contextsumission={"title":title, "form":form}
if form.is_valid():
first_name = form.cleaned_data.get("first_name")
last_name = form.cleaned_data.get("last_name")
validform=True
if validform:
contextupload={"title":"Please upload your files","valid":True}
return render(request, 'submission.html', contextupload)
form2 = UploadForm(request.FILES)
contextsumission={"title":'Upload files', "form2":form2}
if form2.is_valid():
file1 = form2.request.FILES.get("file1")
file2 = form2.request.FILES.get("file2")
contextsumission={"title":"Thank you for your data submission"}
return render(request, 'submission.html', contextsumission)
And I have tried to write my template in a following way
{% if valid %}
<h1 class ='text-align-center', style="color: blue;"> {{ title }} </h1>
<form method ='POST' enctype="multipart/form-data" action =''> {% csrf_token %}
{{form2|crispy}}
<input class='btn btn-primary', type='submit', value='Upload'>
</form>
{% else %}
<h1 class ='text-align-center', style="color: blue;"> {{ title }} </h1>
<form method ='POST' enctype="multipart/form-data" action =''> {% csrf_token %}
{{form|crispy}}
<input class='btn btn-primary', type='submit', value='Submit'>
</form>
{% endif %}
I can see my SubmissionForm clearly in template but after pressing submit button I want to show file upload form but it is not working.
Anyone can please tell me where I need to change my code?
Thanks
Paul
Yes I have realized that and modified my code but still I have problem and def submission function is not validating two forms!! That means when ever I am trying to do form2.is_valid(), is returning false.
def submission(request):
title="Please submit your data"
form = SubmissionForm(request.POST)
contextsubmission={"title":title, "form":form}
if form.is_valid():
first_name = form.cleaned_data.get("first_name")
last_name = form.cleaned_data.get("last_name")
form2 = UploadForm(request.FILES)
contextsubmission ={"title":"Please upload your files","form2":form2,"valid":True}
if form2.is_valid():
file1 = form2.request.FILES.get("file1")
file2 = form2.request.FILES.get("file2")
contextbsumission={"title":"Thank you for your data submission"}
return render(request, 'submission.html', contextsubmission)

Categories

Resources