Using <form> to update BooleanField in Django - django

Using Django 1.6 with Python 2.7.
My model has a BooleanField variable, and I want the user to be able to change this via POST by clicking a button to change it from False to True, or vice versa. Having issues rendering the template.
Model currently:
class Pic(models.Model):
Name = models.CharField(max_length=100)
Good = models.BooleanField()
Image = models.FileField(upload_to="images/")
def __unicode__(self):
return self.Name
App urls is:
url(r'^(?P<Pic_id>\d+)/$', views.single_picture, name='single_picture'),
In the template I have:
<form action="{% url 'single_picture' Pic.Good %}" method="post">
{% csrf_token %}
{% if Pic.Good %}
<input type="checkbox" name="choice" id="{{ Pic.Good }}" value="False" />
<label for="{{ Pic.Good }}">False</label><br />
{% else %}
<input type="checkbox" name="choice" id="{{ Pic.Good }}" value="True" />
<label for="{{ Pic.Good }}">True</label><br />
{% endif %}
<input type="submit" value="good" />
</form>
And for my view I have:
def single_picture(request, Pic_id):
if request.method == 'GET':
pic = get_object_or_404(Pic, pk=Pic_id)
latest_pictures_list = Pic.objects.all()
return render(request, 'pictures/single_picture.html', {'Pic': pic, 'latest_pictures_list': latest_pictures_list})
elif request.method == 'POST':
pic = get_object_or_404(Pic, pk=Pic_id)
latest_pictures_list = Pic.objects.all()
try:
selected_choice = p.choice_set.get(pk=request.POST['choice'])
except (KeyError, Pic.DoesNotExist):
return render(request, 'pictures/single_picture.html', {'Pic': pic, 'error_message': 'uhhhh...',
})
else:
selected_choice.save()
return HttpResponseRedirect(reverse('pictures/single_picture.html', {'Pic': pic}))
I'm not sure if there are multiple errors at this point or not. Currently when trying to view the template, I get
Reverse for 'single_picture' with arguments '(True,)' and keyword arguments '{}' not found. 0 pattern(s) tried: []
for the '< form >' line. I'm guessing it's to do with my View?

I think the issue is in your template, in the line
<form action="{% url 'single_picture' Pic.Good %}" method="post">
Your regex in urls.py is r'^(?P<Pic_id>\d+)/$', I'm guessing that it's expecting the id of the Picobject you return in the GET request and not a boolean, in which case the line should be
<form action="{% url 'single_picture' Pic.id %}" method="post">
Likewise, in the lines underneath, there isid="{{ Pic.Good }}" which will display as HTML as id=True or id=False, which I suppose you don't want. You need to replace that bit by id="{{Pic.id}}"

Related

Why don't my entries get saved in the database in Django?

The post requests from the frontend do not get saved in the database, without any error shown. However, when I manually add entries from the admin panel, it shows on the frontend.
My index.html(form part):
<form class="main__input--form" method="POST">
{% csrf_token %}
<p class="main__input--text">
<textarea name="content" id="content" class="main__input--content" cols="35" rows="8" aria-label="Entry content" placeholder="Enter text here..."></textarea>
</p>
<button class="main__input--submit" type="submit">Vent</button>
</form>
My extension of index which loops through the database entries:
{% for obj in all_vents %}
<div>
<h1>{{obj.vent}}</h1>
</div>
<br />
{% endfor %}
My models.py:
class Vents(models.Model):
vent = models.CharField(max_length=10000)
def __str__(self):
return self.vent
My forms.py:
from django import forms
from .models import Vents
class VentForm(forms.ModelForm):
class Meta:
model = Vents
fields = ['vent']
My views.py:
from django.shortcuts import render, redirect
from .forms import VentForm
from .models import Vents
def ventout(request):
if request.method == "POST":
form = VentForm(request.POST or None)
if form.is_valid():
form.save()
return redirect("ventout")
else:
all_vents = Vents.objects.all()
return render(request, "ventout.html", {"all_vents": all_vents})
Views:
def ventout(request):
all_vents = Vents.objects.all()
if request.method == "POST":
form = VentForm(request.POST or None)
if form.is_valid():
form.save()
return redirect("ventout")
else:
form = VentForm()
context = {"all_vents": all_vents, "form":form}
return render(request, "ventout.html", context)
Template:
<form class="main__input--form" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="main__input--submit">Vent</button>
</form>
you could install/use "crispy_forms_tags" to make the form look better,
https://django-crispy-forms.readthedocs.io/en/latest/index.html
if you want to go further you could install/use "widget_tweaks"
https://pypi.org/project/django-widget-tweaks/
Your index.html from part should have {{ form }} form tag, as I guess.
Try Using following code
<form class="main__input--form" method="POST">
{% csrf_token %}
{{ form }}
<p class="main__input--text">
<textarea name="content" id="content" class="main__input--content"
cols="35" rows="8" aria-label="Entry content" placeholder="Enter text here...">
</textarea>
</p>
<button class="main__input--submit" type="submit" value="Submit">Vent</button>
</form>

How to get the value of a specific field in a form in Django view function?

I am trying to achieve a load-up process in my system where the user will input the load amount and add it to a user's current load.
How can I get the amount entered in my view function?
Here's my function in my views.py
def LoadWallet(request, pk):
user = get_object_or_404(User, id=request.POST.get('user_id'))
user_wallet = user.wallet
if request.method == 'POST':
form = LoadForm(request.POST)
if form.is_valid():
user_wallet = user_wallet+form.instance.load_amount
User.objects.filter(id=pk).update(wallet=user_wallet)
return HttpResponseRedirect(reverse('user-details', args=[str(pk)]))
and the form in my template file
<form action="{% url 'load-wallet' user.pk %}" method="POST">
{% csrf_token %}
<label for="load_amount">Load amount</label>
<input type="text" class="form-control" id="load_amount" onkeyup="replaceNoneNumeric('load_amount')">
<button type="submit" name="user_id" value="{{ user.id }}" class="btn btn-md btn-success" style="float: right; margin: 10px 5px;">Load</button>
</form>
Right now I tried this but it's returning "name 'LoadForm' is not defined". Should I declare the LoadForm first?
Is there a better way to implement this? Thank you!
You might have an easier time using something like this, than LoadForm:
def LoadWallet(request, pk):
user = get_object_or_404(User, id=request.POST.get('user_id'))
user_wallet = user.wallet
if request.method == "POST":
user_id = request.POST["user_id"]
# Other logic here
return ...
And in template
<form class="load-wallet" action="" method="POST">
{% csrf_token %}
<input type="text" name="user_id" placeholder="What is the user id?">
<button type="submit" class="submit-btn"> Submit </button>
</form>

Form wont appear in admin side of website and confused as to why and wondering if someone else could see why

models.py
class Contact(models.Model):
BookID = models.CharField(max_length=30)
BookTitle = models.CharField(max_length=30)
Author = models.CharField(max_length=35)
UploadImage =
models.ImageField(upload_to='ContactImg')
def __str__(self):
return self.BookId
forms.py
class ContactForm(forms.Form):
BookID=forms.CharField(max_length=30,required=True)
BookTitle=forms.CharField(max_length=30,required=True)
Author=forms.CharField(max_length=35,required=True)
UploadImage=forms.ImageField()
class Meta:
model = Contact
fields = ('BookID', 'BookTitle', 'Author','UploadImage')
Views.py
def ContactUs(request):
context_dict = {}
if request.user.is_authenticated:
context_dict['logged_in'] = True
else:
context_dict['logged_in'] = False
user_form=ContactForm()
if request.method == 'POST':
user_form = ContactForm(request.POST)
if user_form.is_valid():
# we load our profile instance
Contact.BookId = user_form.get('BookId')
Contact.BookTitle = user_form.get('BookTitle')
Contact.Author= user_form.get('Author')
Contact.UploadImage= user_form.get('UploadImage')
Contact.save()
return redirect('readingTime:home')
else:
# Invalid form
# messages.error(request, 'Form contains errors. Double check')
print(user_form.errors)
messages.error(request, 'Form contains errors. Double check')
# user_form = user_form.errors
# user_form = RegisterForm()
else:
# Blank form since we do not have an HTTP POST
user_form = ContactForm()
return render(request,"readingTime/ContactUs.html",context=context_dict)
Html
{% extends 'readingTime/base.html' %}
{% load staticfiles %}
{% block style_css %}
<link rel="stylesheet" type="text/css" href="{% static 'css/ContactUs.css' %}"
xmlns="http://www.w3.org/1999/html"/>
{% endblock %}
{% block navigation_bar %}
<div class="navigation-bar">
home
{% if logged_in %}
Sign Out
My account
User Polls
{% else %}
Register
Sign In
Poll Results
{% endif %}
</div>
{% endblock %}
{% block body_block %}
<div class="main" >
<h1>Contact Us</h1>
<div class="main2">
<form id="user_form" class="contact-form" method="post" action="{% url 'readingTime:ContactUs'
%}" enctype="multipart/form-data">
<div class="contact-container">
<h2>Request To Add A Book</h2>
{% csrf_token %}
Bookd Id (ISBN) <input type="text" name="BookID" value="" size="30" />
<br />
Book Title <input type="text" name="BookTitle" value="" size="50" />
<br />
Author(Full Name) <input type="text" name="Author" value="" size="30" />
<br />
Book Cover(Optional)<input type="file" id="UploadImage" name="UploadImage">
<br/>
<!-- Submit button-->
<div>
<button type="submit" class="submit-button">Send Request</button>
</div>
</div>
</form>
<h4>Popular Questions</h4>
<ul>
<li> <div class="Question">How To Sign In ?</br></br>
<Answer>Click on the sign in page button and enter your log in details</Answer></div>
</li>
</br></br></br>
<li> <div class="Question">How to edit my profile?</br></br>You need to be first signed in and then you can navigate to myAccount and click edit profile to change your details</br></div></li>
</br></br></br>
<li> <div class="Question">How to Sign out of my account?</br></br>You need to navigate to the sign out button at the top and press it to sign out</div></li>
</br></br></br>
<li> <div class="Question">How to register for an account?</br></br>Click on the register button at the top of the page in order and then enter your details or go to the sign in page and sign up to register there</div></li></ul>
<!-- action indicates where to send the form when submitted -->
</div>
</div>
{% endblock %}
{% block footer %}
{% endblock %}
I am wondering as to why it wont let me send the information inside the form to admin side of the page as it lets me automaticaly a manual from into the admin side but wont let me recieve the data from the form i create for the contact us page and was wondering if anyone has any ideas as to why this is ?
The way you have done this has a lot of errors.
Lets start again:
Your model looks fine.
forms.py:
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = '__all__'
views.py
from .forms import ContactForm
def ContactUs(request):
if request.user.is_authenticated:
logged_in = True
else:
logged_in = False
if request.method == 'GET':
user_form=ContactForm()
elif request.method == 'POST':
user_form = ContactForm(request.POST)
if user_form.is_valid():
user_form.save()
return redirect('readingTime:home')
context = {
'logged_in': logged_in,
'user_form': user_form
}
return render(request, "readingTime.html", context)
readingTime.html
<form id="user_form" class="contact-form" method="POST" action="{% url'readingTime:ContactUs'%}" enctype="multipart/form-data">
<div class="contact-container">
<h2>Request To Add A Book</h2>
{% csrf_token %}
{{ user_form }}
<!-- Submit button-->
<div>
<button type="submit" class="submit-button">Send Request</button>
</div>
</div>

What is the meaning of redirect_field_value in django

What is the meaning of this code?
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
The above html snip can be used to logout from the django app Example in SO when we are using django-allauth library, redirect_field_value is used in a form to post to the URL account_logout or account/logout and it's associated view takes care of the action
Note: by default redirect_field_name = 'next' which is passed to the function get_next_redirect_url to get the redirect url.
class LogoutView(TemplateResponseMixin, View):
template_name = "account/logout." + app_settings.TEMPLATE_EXTENSION
redirect_field_name = "next"
def post(self, *args, **kwargs):
#self.get_redirect_url method is called by passing the redirect_field_name='next'
#which is used further to logout the authenticated user
url = self.**get_redirect_url()**
if self.request.user.is_authenticated:
self.logout()
response = redirect(url)
return _ajax_response(self.request, response)
def logout(self):
adapter = get_adapter(self.request)
adapter.add_message(
self.request,
messages.SUCCESS,
'account/messages/logged_out.txt')
adapter.logout(self.request)
def get_redirect_url(self):
return (
get_next_redirect_url(
self.request,
**self.redirect_field_name**) or get_adapter(
self.request).get_logout_redirect_url(
self.request))
As I see every view(SignUp,Login,Logout) has the default rediect_field_name defined, so removing above tag will be still function when performing the logout action.
<form method="post" action="{% url 'account_logout' %}">
{% csrf_token %}
<!-- {% if redirect_field_value %}
<input type="hidden" name="{{redirect_field_name}}" value="{{redirect_field_value}}">
{% endif %} -->
<button type="submit" class="nav-link btn btn-sm sgp">SignOut</button>
</form>

get_query_set(self) is not being called in django

I am implementing search function using TemplateView in Django the class is
class part_search_view(TemplateView):
model = part_list
context_object_name = 'part_list'
template_name = 'part_list.html'
def get_context_data(self, **kwargs):
context = super(part_search_view, self).get_context_data(**kwargs)
context['my_list'] = populate_nav_bar()
return context
def get_queryset(self):
key = self.request.GET['search_text']
partlist = part_list.objects.filter(Q(part_id__icontains=key) | Q(part_name__icontains=key))
return partlist
part_list.html
{% for part in part_list %}
{{ part.part_id }} - {{ part.part_name }}
<a href="{% url 'parts:part_update_view' part.id %}" > Edit </a>
{% endfor %}
the url mapping is
url(r'^search/',views.part_search_view.as_view(),name='part_search_view'),
the form for serch button
<form action="{% url 'parts:part_search_view'%}" role="form" class="navbar-form navbar-left" method="get" >
{% csrf_token %}
<div class="form-group ">
<input class="form-control mr-sm-2" type="text" placeholder="Search" name="search_text">
<button class="form-control search_buton btn btn-success " type="submit" >Search</button>
</div>
</form>
after the search button is pressed the address is
http://127.0.0.1:8000/parts/search/?csrfmiddlewaretoken=PWjEw1hRsyH9B6YcseVuhS0urX8L7f170q9ucLF9hTPQPThulpgMSP4y5xhScCVr&search_text=mp6
but the get_query_set(self) is not called here the get_context_data(...) is called though, why?
TemplateViews don't know anything about querysets, so they never call a get_queryset method. You should subclass a more appropriate view, perhaps ListView.
If you look at docs, TemplateView does not have a method get_queryset(). Then, you would have to manually call it in the view.