I'm pretty new in programming and I did the Django tutorial 'Writing your first Django app'. Now I want to make some changes to this app and I do not really know how to do it.
I want to set several labels with different images for each choice.id in the following input for loop:
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
<input type="submit" value="Vote">
</form>
models.py
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
class Choice(models.Model):
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
question = models.ManyToManyField(Question)
def __str__(self):
return self.choice_text
view.py
def index(request):
latest_question_list = Question.objects.order_by('pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
I'd really appreciate some help about this.
Thanks!
Related
Hello I'm new to Django I'm trying to create my first application with Django using an API that return JSON.I want to know how to save this data to my database. this is the code I have so fat. forms.py:
from django import forms
import requests
from .models import Series
API_KEY = 'api_key'
class SeriesAPI(forms.Form):
serie = forms.CharField(label='Search for Serie', max_length=100)
def search(self):
result = {}
serie = self.cleaned_data['serie']
endpoint = 'https://api.themoviedb.org/3/search/tv?api_key={api_key}&query={serie_name}'
url = endpoint.format(
api_key = API_KEY,
serie_name = serie
)
response = requests.get(url)
if response.status_code == 200:
result = response.json()
if result['total_results'] >= 1:
id = result['results'][0]['id']
else:
return None
return id
def get_serie(self):
result = {}
endpoint = 'https://api.themoviedb.org/3/tv/{id}?language=en-US&api_key={api_key}'
url = endpoint.format(
id = self.search(),
api_key = API_KEY
)
response = requests.get(url)
if response.status_code == 200:
result = response.json()
return result
Right now everything's good, I got the data and I can display it; I create a new form with only one input to store the data but I can't do it
this is my views.py:
def index(request):
search_result = {}
form = SeriesAPI(request.POST or None)
if 'serie' in request.POST:
if form.is_valid():
search_result = form.get_serie()
else:
form = SeriesAPI()
return render(request, 'series/serie.html', {'form': form, 'search_result': search_result})
class CreateSeries(generic.CreateView):
fields = ('original_name', 'overview')
model = models.Series
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.save()
return super(CreateSeries, self).form_valid(form)
and this my template:
{% extends "series/base_series.html" %}
{% block content %}
<h1>Series</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Search</button>
</form>
{% if search_result %}
<hr>
<h2>{{search_result.name}}</h2>
<img src="http://image.tmdb.org/t/p/original{{ search_result.poster_path }}" alt="" style="width:250px;">
<form method="GET">
<button type="submit">Add</button>
</form>
{% else %}
<p>Serie Not Found!</p>
{% endif %}
{% endblock %}
Please help me
Why is the form not showing in the browser?
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ structure.name }} - Details</title>
</head>
<body>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<h3>Structure: {{ structure }}</h3>
<h3>Ajouter enregistrement</h3>
<form action="{% url 'Structure:addrecord' structure.id %}" method="post">
{% csrf_token %}
{% for structure in all_structures %}
<input type="radio" id="record{{ forloop.counter }}" name="record" value="record.id">
<label for="record{{ forloop.counter }}">
Nom de l'enregistrement: {{ record.record_name }}
</label>
{% endfor %}
</form>
</body>
</html>
When I test this in my browser, and inspect it, it gives me a form of this size: 1340px * 0 px.
I even explicitly gave a style="height: 500px", but it still gives me an empty form.
Here's a screenshot
Thanks for the help guys!
Edit:
Views.py:
from django.shortcuts import render, get_object_or_404
from .models import Structure, Record
def index(request):
all_structures = Structure.objects.all()
return render(request, 'Structures/index.html', {'all_structures': all_structures})
def detail(request, structure_id):
#structure = Structure.objects.get(pk=structure_id)
structure = get_object_or_404(Structure, pk=structure_id)
return render(request, 'Structures/details.html', {'structure': structure})
def addRecord(request, structure_id, record.name, record.type, record.pos, record.long):
r = Record(structure='structure_id', name='record.name', type='record.type', pos='str(record.pos)', long='str(record.long)')
r.save()
return render(request, 'Structures/details.html', {'structure': structure})
Also, I do not quite understand this yet because I am using a video tutorial series by thenewboston's channel, the variables I am using in addRecord are not known, and I want to use them from the model. Here are the models and urls files as well:
models.py:
from django.db import models
class Structure(models.Model):
name = models.CharField(max_length=120)
path = models.CharField(max_length=200)
def __str__(self):
return self.name
class Type(models.Model):
typename = models.CharField(max_length=50)
def __str__(self):
return self.typename
class Record(models.Model):
structure = models.ForeignKey(Structure, on_delete=models.CASCADE) #each structure has many records, each per line
name = models.CharField(max_length=200)
type = models.ForeignKey(Type)
pos = models.IntegerField()
long = models.IntegerField()
def __str__(self):
return self.name
urls.py:
from django.conf.urls import url
from . import views
app_name = 'Structure'
urlpatterns = [
# /structures/
url(r'^$', views.index, name='index'),
# /structures/id
url(r'^(?P<structure_id>[0-9]+)/$', views.detail, name='detail'),
# /structures/addrecord
url(r'^(?P<structure_id>[0-9]+)/addrecord/$', views.addRecord, name='addrecord'),
]
Look for the value of all_structures that you are passing in context from views.
If it is empty or not passed, form fields won't be displayed as per your template code.
Try to print its value either in the console or in template. That's how to Debug.
Hope this helps.
I am able to upload the profile picture but i am not able edit it
I have the form populating with the image browse option, but when I click save, it doesn't actually update in template. but it is working fine in admin
views.py
def create_form(request):
form = AlbumForm(request.POST or None, request.FILES or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.image= request.FILES['image']
album.save()
return render(request, 'about.html', {'album': album})
context = {
"form": form,
}
return render(request, 'create_form.html', context)
def profile_edit(request):
if request.method == 'POST':
form = AlbumForm(request.POST, instance=request.user.album)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
form.save()
return redirect(reverse('about'))
else:
form = AlbumForm(instance=request.user.album)
args = {'form': form}
return render(request, 'profile_edit.html', args)
models.py
class Album(models.Model):
user = models.OneToOneField(User)
image = models.FileField()
forms.py
class AlbumForm(forms.ModelForm):
class Meta:
model = Album
fields = ['image']
profile_edit.html
{% extends 'base.html' %}
{% block content %}
<form action="{% url 'profile_edit' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">save</button>
</form>
<div>
<img src="{{ user.album.image.url }}" class="img-responsive">
</div>
{% endblock %}
Try this
AlbumForm(request.POST, request.FILES, instance=request.user.album)
You need to add request.FILES to your AlbumForm in the profile edit view.
If you upload file you must use request.Files
read for more info this link
https://docs.djangoproject.com/en/1.10/topics/http/file-uploads/#basic-file-uploads
I am trying to output an error message in my html. I tried using the advice of other questions but I'm still getting the error at the traceback screen, not on the html. Can someone help?
The is my view:
def add_user_institution_accounts(request):
context_object_name = 'variable_used_in `add_user_accounts.html`'
form = AddUserAccountsForm
template_name = 'add_user_accounts.html'
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = AddUserAccountsForm(request.POST)
# check whether it's valid:
if form.is_valid():
Institution = Institution.objects.get(name=form.cleaned_data['name'])
new_entry = User.objects.get(id=request.user.id)
if Account.objects.filter(user=new_entry, institution=Institution.type).exists():
raise forms.ValidationError(_('This account already exists'), code='invalid')
else:
Account.objects.create(user=new_entry, institution = Institution.type)
return HttpResponseRedirect('')
else:
messages.error(request, "Error")
return render(request, 'add_user_accounts.html',
{'form': form},
{'form_errors': form_errors},
context_instance=RequestContext(request))
My html is:
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block content %}
{% load staticfiles %}
<script type="text/javascript" src="{% static 'jquery.js' %}"></script>
{% include 'autocomplete_light/static.html' %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
{{ form.errors }}
<input type="submit" value="Add account" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
This is the traceback error:
ValidationError at /profile/add_user_accounts/
[u'This account already exists']
occurring on this line:
raise forms.ValidationError(_('This account already exists'), code='invalid')
You have to do the validation error in forms;
class AddUserAccountsForm(forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(AddUserAccountsForm, self).__init__(*args, **kwargs)
def clean_name(self):
Institution = Institution.objects.get(name=self.cleaned_data['name'])
new_entry = User.objects.get(id=self.request.user.id)
if Account.objects.filter(user=new_entry, institution=Institution.type).exists():
raise forms.ValidationError(_('This account already exists'), code='invalid')
return self.cleaned_data['name']
in views;
form = AddUserAccountsForm(request.POST, request=request)
#GeoJacob Thanks. To solve the user id issue, I used the following code:
def clean_name(self):
Institution = Institution_long_tail.objects.get(name=self.cleaned_data['name'])
current_user = wellfyUser.objects.get(id=self.instance.id)
if Access_token_pair.objects.filter(user=current_user, institution=Institution.type).exists():
raise forms.ValidationError(_('This account already exists'), code='invalid')
return self.cleaned_data['name']
with view:
form = AddUserAccountsForm(request.POST, instance=current_user)
I am trying to create a contact form for my Django site but it's not working properly. There are three steps to the contact form. Step 1 has a box where you input the subject of the email. Step 2 has a box where you input the sender's email address. At this point, there are three buttons- "first step", "prev step", and "submit". If I click "submit", the site doesn't take me to step 3, which is supposed to be where you input the body of the email. Instead, it reroutes me back to the Step 1 page.
I did my research and I can't find anything online related to this particular problem.
Here is my views.py file, which is located in the django_test/django_test directory:
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from forms import MyRegistrationForm
from django.contrib.formtools.wizard.views import SessionWizardView
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
#import logging
#logr = logging.getLogger(__name__)
def login(request):
c = {}
c.update(csrf(request))
return render_to_response('login.html', c)
def auth_view(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return HttpResponseRedirect('/accounts/loggedin')
else:
return HttpResponseRedirect('/accounts/invalid')
def loggedin(request):
return render_to_response('loggedin.html',
{'full_name': request.user.username})
def invalid_login(request):
return render_to_response('invalid_login.html')
def logout(request):
auth.logout(request)
return render_to_response('logout.html')
def register_user(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
args = {}
args.update(csrf(request))
args['form'] = MyRegistrationForm()
return render_to_response('register.html', args)
def register_success(request):
return render_to_response('register_success.html')
class ContactWizard(SessionWizardView):
template_name = "contact_form.html"
def done(self, form_list, **kwargs):
form_data = process_form_data(form_list)
return render_to_response('done.html', {'form_data': form_data})
def process_form_data(form_list):
form_data = [form.cleaned_data for form in form_list]
logr.debug(form_data[0]['subject'])
logr.debug(form_data[1]['sender'])
logr.debug(form_data[2]['message'])
send_mail(form_data[0]['subject'],
form_data[2]['message'], form_data[1]['sender'],
[(my email address], fail_silently=False)
return form_data
This my forms.py file, also located in the django_test/django_test directory:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class MyRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
class ContactForm1(forms.Form):
subject = forms.CharField(max_length=100)
class ContactForm2(forms.Form):
sender = forms.EmailField()
class ContactForm3(forms.Form):
message = forms.CharField(widget=forms.Textarea)
And my contact_form.html file, located in the django_test/templates directory:
{% extends "base.html" %}
{% block content %}
<h2>Contact Us</h2>
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
{% for field in form %}
{{field.error}}
{% endfor %}
<form action="/contact/" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form }}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">"first step"</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">"prev step"</buttom>
{% endif %}
<input type="submit" value="submit" />
</form>
{% endblock %}
And this is my urls.py file:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
from django_test.api import ArticleResource
from django_test.forms import ContactForm1, ContactForm2, ContactForm3
from django_test.views import ContactWizard
article_resource = ArticleResource()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^accounts/login/$', 'django_test.views.login'),
url(r'^accounts/auth/$', 'django_test.views.auth_view'),
url(r'^accounts/loggedin/$', 'django_test.views.loggedin'),
url(r'^accounts/invalid/$', 'django_test.views.invalid_login'),
url(r'^accounts/logout/$', 'django_test.views.logout'),
url(r'^accounts/register/$', 'django_test.views.register_user'),
url(r'^accounts/register_success/$', 'django_test.views.register_success'),
url(r'^articles/all/$', 'article.views.articles'),
url(r'^articles/create/$', 'article.views.create'),
url(r'^articles/get/(?P<article_id>\d+)/$', 'article.views.article'),
url(r'^articles/like/(?P<article_id>\d+)/$', 'article.views.like_article'),
url(r'^articles/add_comment/(?P<article_id>\d+)/$', 'article.views.add_comment'),
url(r'^articles/search/', 'article.views.search_titles'),
url(r'^articles/api/', include(article_resource.urls)),
url(r'^contact/', ContactWizard.as_view([ContactForm1, ContactForm2, ContactForm3])),
)
I'm not getting any error messages either, which is frustrating, so I don't know what I'm doing wrong. Thank you.
All I had to do was view the page source on the site. It turned out
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">"prev step"</buttom>
in contact_form.html had a typo: </buttom>. I fixed the error and now I get the comment page.
The line should be:
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">"prev step"</button>