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
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>
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).
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
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.
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