django form how to render the fields - django

I'm trying to render a form but the fields are not displayed in the HTML.
views.py
#url(r'^boxes/(?P<pk>[0-9A-Za-z-]+)/$', views.show_form, name='box'),
def show_form(request, pk):
box = Box.objects.get(pk=pk)
form = SuggestionForm()
context = {
'box':box,
'form':form
}
return render(request, 'boxes/detail.html', context)
forms.py
class SuggestionForm(ModelForm):
class Meta:
model = Suggestion
fields = ['comment']
detail.html
<h3>{{box.title}}</h3>
<form action="." method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-info" value="Add suggies" />
</form>
My models.py
#python_2_unicode_compatible
class Suggestion(models.Model):
"""
For adding comments (or suggestions)
"""
def __str__(self):
return self.comment[0:10]
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
comment = models.CharField("",max_length=250, blank=True, null=True)
box = models.ForeignKey(Participant, on_delete=models.CASCADE)
created_at = models.DateField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
The result HTML.. There is no fields in this form. I want to use a function based view.

Related

Djago time widget not showing up

All I want to do is add time widget to my form so I can easily pick the time. Everything is very simple, the page is loading but the widgets don't show up. No error nothing. I am thinking maybe I didn't set up the form widgets correctly but not sure what I did wrong. Here is my Forms.py-
from django.contrib.admin import widgets
from django.contrib.admin.widgets import AdminDateWidget, AdminTimeWidget, AdminSplitDateTime
class WorkOutForm(ModelForm):
class Meta:
model = WorkOut
fields = '__all__'
widgets={
'start':AdminTimeWidget(),
'end':AdminTimeWidget(),
}
Here is the Models.py. You will notice "start" and "end" fields are timefield-
class WorkOut(models.Model):
date=models.DateField(auto_now_add=True, auto_now=False, blank=True)
day=models.DateField(auto_now_add=True, auto_now=False, blank=True)
start=models.TimeField(null=True)
name=models.CharField(max_length=100, choices=move)
weight=models.CharField(max_length=100, blank=True)
rep=models.CharField(max_length=100, blank=True)
pedal= models.CharField(max_length=100, blank=True)
stretchtype =models.CharField(max_length=100, blank=True)
end=models.TimeField(null=True)
note=models.TextField(max_length=300, blank=True)
def __str__(self):
return self.name
And here are the views linked to it even though I don't think it has much relevance-
def workout(request):
form=WorkOutForm()
if request.method=="POST":
form=WorkOutForm(request.POST)
if form.is_valid():
form.save()
context={'form':form}
return render(request, 'myapp/enter_workout.html', context)
def update_workout(request, pk):
order=WorkOut.objects.get(id=pk)
form=WorkOutForm(instance=order)
if request.method=='POST':
form=WorkOutForm(request.POST, instance=order)
if form.is_valid():
form.save()
context={'form':form}
return render(request, 'myapp/enter_workout.html', context)
And the form on HTML page is also very basic,so don't think there is any issue there either-
<form action="" method="POST">
{% csrf_token %}
{{form}}
<input type="submit" value="Submit">
</form>
What have I done wrong here? How can I make those widgets to show up?
You can try to fill the default values with the current time.
from datetime import datetime
class WorkOut(models.Model):
move = (("1", "Tom"), ("2", "Sara"), ("3", "Emilia"),)
date = models.DateField(auto_now_add=True, auto_now=False, blank=True)
day = models.DateField(auto_now_add=True, auto_now=False, blank=True)
start = models.TimeField(default=datetime.now, null=True)
name = models.CharField(max_length=100, choices=move)
weight = models.CharField(max_length=100, blank=True)
rep = models.CharField(max_length=100, blank=True)
pedal = models.CharField(max_length=100, blank=True)
stretchtype = models.CharField(max_length=100, blank=True)
end = models.TimeField(default=datetime.now,null=True)
note = models.TextField(max_length=300, blank=True)
def __str__(self):
return self.name
Update 22.10.2022
Made fields with time selection on bootstrap.
For this you need to install:
pip install django-bootstrap4
pip install django-bootstrap-datepicker-plus
In the WorkOutForm class in init set the styles for all fields.
forms.py
from bootstrap_datepicker_plus.widgets import TimePickerInput
class WorkOutForm(ModelForm):
class Meta:
model = WorkOut
fields = "__all__"
widgets = {
"start": TimePickerInput(),
"end": TimePickerInput(),
}
def __init__(self, *args, **kwargs):
super(WorkOutForm, self).__init__(*args, **kwargs)
for field in iter(self.fields):
self.fields[field].widget.attrs.update({
"class": "form-control"
})
templates
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{{ form.media }}
<form action="" method="POST" style="width: 20%">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>

Django - How to display multpile choices for Polls app

Following along the Django polls app tutorial, I was wondering if instead of having a Charfield for the choice Model and manually adding every response/choice to the database; Is it possible to have choices?
For example:
class Poll(models.Model):
text = models.CharField(max_length=255)
pub_date = models.DateField()
def __str__(self):
return self.text
class Choice(models.Model):
question = models.ForeignKey(Poll, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=255)
votes = models.IntegerField(default=0)
def __str__(self):
return "{} - {}".format(self.question.text[:25],
self.choice_text[:25])
You have standard choices for every Poll like this:
class Poll(models.Model):
text = models.CharField(max_length=255)
pub_date = models.DateField()
def __str__(self):
return self.text
class Choice(models.Model):
VOTING_CHOICES = (
('Aye', 'Aye'),
('Nay', 'Nay'),
('Abstain', 'Abstain'),
)
question = models.ForeignKey(Poll, on_delete=models.CASCADE)
choice_text = models.CharField(
max_length=7,
choices=VOTING_CHOICES,
default='Aye',
)**
votes = models.IntegerField(default=0)
def __str__(self):
return "{} - {}".format(self.question.text[:25],
self.choice_text[:25])
Poll Detail page
========
{{ poll }}
<form action="" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
{% for i,k in choice.VOTING_CHOICES %}
<input type="radio"
name="option"
id="choice{{forloop.counter}}"
value="{{ i }}"/>
<label for="choice{{forloop.counter}}">{{ k }}</label>
{% endfor %}
{% endfor %}
<input type="submit" value="Vote">
</form>
views.py
def poll_detail(request, poll_id):
#render poll detail page
poll= get_object_or_404(Poll, id=poll_id)
if request.method =="POST":
print(request.POST)
# Debug to see what data I am posting on form submission
context = {
'poll':poll,
}
return render(request, 'app/poll_detail.html', context)
Does that make sense? Every time I try to implement this, I either get an empty dictionary response when I POST from the form or the options show up in tuples(or do not render at all).

Django - saving model via a form is not working

I'm having a little problem with the .save() method in Django. For 1 form it works, for the other it doesn't. And I can't find the problem.
views.py
#login_required
def stock_add(request, portfolio_id):
if request.method == 'POST':
print('request.method is ok')
form = StockForm(request.POST)
print('form is ok')
if form.is_valid():
print('form is valid')
stock = form.save(commit=False)
stock.created_by = request.user
stock.portfolio_id = portfolio_id
stock.save()
return redirect('portfolio-overview')
else:
print("nope")
else:
print('else form statement')
form = StockForm()
context = {
'form':form
}
return render(request, 'portfolios/stock-add.html', context)
forms.py
class StockForm(ModelForm):
class Meta:
model = Stock
fields = ['quote', 'amount']
html
{% extends 'core/base.html' %}
{% block content %}
<div class="container">
<h1 class="title">Add Stock</h1>
<form method="POST" action=".">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="button is-primary">Submit</button>
</form>
</div>
{% endblock %}
models
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Portfolio(models.Model):
title = models.CharField(max_length=56)
description = models.TextField(blank=True, null=True, max_length=112)
created_by = models.ForeignKey(User, related_name='portfolios', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'Portfolio'
def __str__(self):
return self.title
class Stock(models.Model):
Portfolio = models.ForeignKey(Portfolio, related_name='stocks', on_delete=models.CASCADE)
quote = models.CharField(max_length=10)
amount = models.IntegerField()
created_by = models.ForeignKey(User, related_name='stocks', on_delete=models.CASCADE)
created_at = models.DateField(auto_now_add=True)
def __str__(self):
return self.quote
If you look at the views.py file, when I submit the form, it won't even do print('request.method is ok')
I can add the stock via the admin page.
So I have no clew where to look anymore...
Cheers
When you post a form and need a special url (like your' with an attribute), i like to set action="{% url myview.views.stock_add portfolio_id %}"
action="." will save to the same page without taking care of extra parameters (if needed)
Just pass portfolio_id in the context and that will work
I found the answer, an InteregerField (from models.py) needs a default value.
Either default=None (or another value).
Cheers

In Django getting errors based on dropdown selection

Getting error when fields are selected from the down. Not seeing why it is throwing error
Django Dropdown form.error: ERROR ALERT:
location_name Select a valid choice. That choice is not one of the available choices.
Here is the model, form, view and html looks like
MODEL
class Code (models.Model):
name = models.CharField(max_length=4, default=None, blank=True)
def __str__(self): return self.name
class Device (models.Model):
code = models.ForeignKey(Code, on_delete=models.CASCADE, null=True)
ip = models.GenericIPAddressField(protocol='IPv4', unique=True)
def __str__(self): return self.ip
class SiteData (models.Model):
site = models.ForeignKey(Code, on_delete=models.SET_NULL, null=True)
site_ip = models.ForeignKey(Device, on_delete=models.SET_NULL, null=True)
site_data1 = models.CharField(max_length=3, default='120')
class CombineData(models.Model):
location = models.ForeignKey(Code, on_delete=models.SET_NULL, null=True)
device = models.ForeignKey(AddData, on_delete=models.SET_NULL, null=True)
locdata = models.ForeignKey(SiteData, on_delete=models.SET_NULL, null=True)
FORM
class CombineData_form(forms.ModelForm):
class Meta:
model = P2_NexusLeafPair
fields = '__all__'
VIEW
def comboView(request, *args, **kwargs):
template_name = 'site_display.html'
code = Code.objects.order_by('-name')
device = Device.objects.order_by('-ip')
sitename = SiteData.objects.order_by('-site')
content = {
'code': code,
'device': device,
'sitename': sitename
}
if request.method == 'POST':
form = CombineData_form(request.POST or None)
print(form.is_valid())
#print(form.errors)
if form.is_valid():
. . .
else:
messages.error(request, form.errors)
else:
form = CombineData_form()
return render(request, template_name, content)
HTML
<form id="comboView" class="post-form" role=form method="POST" action="comboView">{% csrf_token %}
<div name="code" class="dropdown" id="mainselection" required>
<select name="dc_name">
<option class="dropdown-item" value="">---------</option>
{% for item in code %}
<option value="{{ item }}">{{ item }}</option>
{% endfor %}
</div>
<input type="submit" value="Submit" />
</form>
{same as other fields: device, sitename}
{% for item in content %}
{{item.code}}
{% endfor %}
Try that.

django updateview return blank template

here is in my models.py:
class Segment(models.Model):
email_segment_name = models.CharField(max_length=200)
email_segment_status = models.BooleanField()
user = models.ForeignKey(User,on_delete=models.SET_NULL,blank=True,null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.email_segment_name
and forms.py:
class SegmentForm(forms.ModelForm):
class Meta:
model = Segment
fields = ['email_segment_name']
labels = {
'email_server_name':('Server Name'),
}
and views:
#method_decorator(login_required, name='dispatch')
class SegmentUpdate(UpdateView):
model = Segment
form_class = SegmentForm
template_name_suffix = '_update_form'
success_url = '/emails/segment'
segment_update_form.html:
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update" />
</form>
the FormView and DeleteView just works fine, but when I update the form, it response with 200 OK and the page is blank, any ideas?
change:
method='post'
to:
method='get'
in segment_update_form.html