I need to get the data from a form in a Django database. The problem when I use .cleaned_data['name'] I am getting an attribute error
'SnippetForm' object has no attribute 'cleaned_data'.
when I tried passing through if old_form.is_valid(), the if is False.
With my code, I can get the HTML info, but I can not parser it with .clean_data.
Basically I don't want to create a regex and parse the html, I am looking for some Django Method that can help.
Html code got from Django:
<tr><th><label for="id_name">Name:</label></th><td><input type="text" name="name" value="Ariel" maxlength="100" id="id_name"></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input type="email" name="email" value="as#onsemi.com" maxlength="254" id="id_email"></td></tr>
<tr><th><label for="id_subject">Subject:</label></th><td><input type="text" name="subject" value="Test" maxlength="100" id="id_subject"></td></tr>
<tr><th><label for="id_body">Body:</label></th><td><textarea name="body" cols="40" rows="10" id="id_body">
This is a test</textarea></td></tr>
In my views.py
def data_detail (request, request_id):
data_detail_django = get_object_or_404(Snippet, pk=request_id)
if request.method == "POST": #Also, it is not going throu this if...
old_form = SnippetForm(request.POST, instance=data_detail_django)
else: #The old_form is the html output and is get it with this
old_form = SnippetForm(instance=data_detail_django)
if old_form.is_valid():
print(old_form.cleaned_data['name'])
return HttpResponse("contact view")
In my models
from django.db import models
# Create your models here.
class Snippet(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
subject = models.CharField(max_length=100, blank=True, null=True)
body = models.TextField(blank=True, null=True)
def __str__(self):
return self.name
in my form.py
from django import forms
from .models import Snippet
class SnippetForm(forms.ModelForm):
class Meta:
model = Snippet
fields = ('name', 'email','subject', 'body')
The solution was: Uning .objects.get(pk = vaule)
def data_detail (request, request_id):
data_dbs = Snippet.objects.get(pk= request_id)
data_out = {'data_dbs': data_dbs}
return render(request, 'form_app/detail.html', data_out )
and in the html to render:
{% extends 'form_app/base.html' %}
{% block main_content %}
{% if data_dbs %}
<p>Name: {{data_dbs.name}}</p>
<p>Email: {{data_dbs.email}}</p>
<p>Subject: {{data_dbs.subject}}</p>
<p>Body: {{data_dbs.body}}</p>
{% else %}
<p> No data</p>
{% endif %}
<a href = '/data'><b>See Form</b></a></li>
{% endblock %}
Related
I am new in Django and i am making a typical CRUD app. In the "add" section, in the comment textarea this message appears "
<django.db.models.query_utils.DeferredAttribute object at 0x03B446A0>"
and i dont know what to do. I had tried multiples solutions in other stackoverflow questions but i cant find the solutions!
Here's the code
class Turno(models.Model):
date = models.DateTimeField()
person = models.ForeignKey('Person', on_delete=models.CASCADE)
medic = models.ForeignKey('Medic', on_delete=models.CASCADE)
observations = models.CharField(blank=True, max_length=255)
def __str__(self):
return f'{self.date} {self.person} {self.medic}'
def new_turn(request):
if request.method == 'POST':
turnFormPost = TurnForm(request.POST)
if turnFormPost.is_valid():
turnFormPost.save()
return redirect("admin_index")
turnForm = TurnForm(instance=Turno)
context = {
'form':turnForm
}
return render(request,"turn_new.html", context)
class TurnForm(ModelForm):
class Meta:
model = Turno
fields = '__all__'
widgets = {
'date': DateTimeInput(attrs={'type':'date'}),
'observations': Textarea(attrs={'rows':5, 'cols':50})
}
-turn_new.html
<div class="container">
<h2>New Turn</h2>
<form method="POST">
{% csrf_token %}
<table>
{{form}}
</table>
<button type="submit" class="btn btn-primary">Create</button>
</form>
<div>
Back to index
</div>
</div>
in the textarea of 'observations' in 'turn_new.html' the message that appears is this
"<django.db.models.query_utils.DeferredAttribute object at 0x03B446A0>"
ValueError at /students/addgrregister/
i am trying to add students in gr_register but its giving an error due to this error the code is not working i also upload the template (addgrregister.html) kndly tell me where is the issue in these pages
models.py
class gr_register(models.Model):
Gender_Choices = (
('M', 'Male'),
('FM', 'Female'),
)
Status_Choices = (
('P', 'Present'),
('FM', 'Left'),
)
gr_no = models.IntegerField(primary_key=True)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_birth = models.DateField(null=True)
classes_A = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name="classes_A", default=1, verbose_name="Class of Admission")
sections_A = models.ForeignKey(Sections, on_delete=models.CASCADE, related_name="sections_A", default=1, verbose_name="Section of Admission")
gender = models.CharField(max_length=10, choices=Gender_Choices)
classes_C = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name="classes_C", verbose_name="Current Class")
sections_C = models.ForeignKey(Sections, on_delete=models.CASCADE, related_name="sections_C", verbose_name="Current Section")
address = models.CharField(max_length=100, null=True, verbose_name="Home Address")
area_code = models.ForeignKey(Area, on_delete=models.CASCADE, verbose_name="Area")
status = models.CharField(max_length=10, choices=Status_Choices, default='P')
class Meta:
ordering = ('gr_no',)
def __str__(self):
return self.first_name
views.py
from django.shortcuts import get_object_or_404, render, redirect
def addgrregister(request):
if request.method == 'POST':
form = gr_registerForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form = gr_registerForm()
return render(request, 'students/addgrregister.html', {'form': form})
forms.py
from django import forms
from django.forms import ModelChoiceField, ModelForm
from .models import *
class gr_registerForm(ModelForm):
classes_A = forms.ModelChoiceField(queryset=Classes.objects.all())
sections_A = forms.ModelChoiceField(queryset=Sections.objects.all())
classes_C = forms.ModelChoiceField(queryset=Classes.objects.all())
sections_C = forms.ModelChoiceField(queryset=Sections.objects.all())
area_code = forms.ModelChoiceField(queryset=Area.objects.all())
class Meta:
model = gr_register
fields = '__all__'
def init(self, *args, **kwargs):
forms.ModelForm.init(self, *args, **kwargs)
addgrregister.html
{% extends 'authenticate/base.html' %}
{% block content %}
<div class="container">
<h4 class="text-center">ADD GR_REGISTER</h4>
<hr/>
<form method="POST" action="{% url 'addgrregister' %}" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="form-group row">
<label for="id_{{ field.name }}" class="col-2 col-form-label">{{ field.label }}</label>
<div class="col-10">
{{ field }}
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary" name="button">Add GR_REGISTER</button>
</form>
<br/><br/>
</div>
{% endblock %}
There is nothing returned when form is not valid. I think you try like this:
def addgrregister(request):
form = gr_registerForm(request.POST or None) # it initates a form. If the request type is POST, then there will be a dict available with posted data in request.POST. If request is not POST, then the form will initiate with empty data.
if request.method == 'POST':
if form.is_valid(): # Form valid checks if the submitted form is valid or not. If not, it will store errors in the form. When that form is passed to template, it will show errors in html
form.save() # It will store data in DB
return redirect('home')
# when for is invalid, it will show the error in the form
return render(request, 'students/addgrregister.html', {'form': form})
Update
Show form errors in template:
{% for field in form %}
<div class="form-group row">
<label for="id_{{ field.name }}" class="col-2 col-form-label">{{ field.label }}</label>
<div class="col-10">
{{ field }}
{{ field.errors }} // <-- Updated here
</div>
</div>
{% endfor %}
I am currently struggling to get my form to work properly. I created the form manually (template.html) and I can see all the data when I call it with print(request.POST) (in views.py - checkout) however form.is_valid(): (in views.py - checkout) doesn't work. Means my form is not valid.
I think the issue is, that I created the form manually and combined it with a model form where I want after validating my data with form.valid() save it in. Can anyone of you guys help me with my problem, why it's not valid?
template.html
<form action="{% url 'checkout:reserve_ticket' %}" method="post">
{% csrf_token %}
{% for ticket in event.tickets.all %}
<p>
{{ ticket.name }} for {{ ticket.price_gross }} with quantity:
<input type="hidden" name="order_reference" value="123456af">
<input type="hidden" name="ticket" value="{{ ticket.id }}">
<input type="hidden" name="ticket_name" value="{{ ticket.name }}">
<input type="number" name="quantity" max="{{ ticket.event.organiser.max_quantity_per_ticket }}" placeholder="0">
</p>
{% endfor %}
<button type="submit" class="btn btn-primary">Continue</button>
</form>
models.py
class ReservedItem(models.Model):
order_reference = models.CharField(
max_length=10,
unique=True
)
ticket = models.ForeignKey(
Ticket,
on_delete=models.PROTECT,
related_name='reserved_tickets'
)
ticket_name = models.CharField(max_length=100)
quantity = models.IntegerField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
forms.py
class ReserveForm(forms.ModelForm):
class Meta:
model = ReservedItem
fields = ['order_reference', 'ticket', 'ticket_name', 'quantity']
views.py - events
# Create your views here.
class EventDetailView(DetailView):
context_object_name = 'event'
def get_object(self):
organiser = self.kwargs.get('organiser')
event = self.kwargs.get('event')
queryset = Event.objects.filter(organiser__slug=organiser)
return get_object_or_404(queryset, slug=event)
views.py - checkout
def reserve_ticket(request):
if request.method == 'POST':
form = ReserveForm(request.POST)
if form.is_valid():
print("Hello World")
return redirect("https://test.com")
else:
print("back to homepage")
I'm writing a django app, and I'd like for users to be able to select a [team_number] from a dropdown menu, then when they hit submit be redirected to a page that renders out the database information associated with that selection. I'm using the redirect class View, but the problem I'm having is that there is no dropdown menu showing up to select [team_number] from on the html page team-stats.html.
views.py:
class TeamStatsView(View):
def get(self, request, *args, **kwargs):
return render(request, 'team-stats.html',
{'team_number': TeamStats()})
def post(self, request, *args, **kwargs):
team_number = TeamStats(request.POST, request.FILES)
if team_number.is_valid():
# do stuff & add to database
team_number.save()
team_number = TeamStats.objects.create()
# use my_file.pk or whatever attribute of FileField your id is
# based on
return HttpResponseRedirect('/team-stats/%i/' % team_number.pk)
return render(request, 'team-stats.html', {'team_number': team_number})
models.py:
class Team(models.Model):
team_number = models.IntegerField()
team_notes = models.CharField(max_length=150)
event_id = models.ForeignKey(
'Event', on_delete=models.CASCADE, unique=False)
def __unicode__(self):
return str(self.team_number)
class Meta:
db_table = 'teams'
app_label = 'frcstats'
forms.py:
class TeamStats(forms.ModelForm):
class Meta:
model = Team
fields = ['team_number']
team-stats.html:
<form method="post" action="">
{% csrf_token %} {{ TeamStatsView }}
<input type="submit" value="Submit" />
</form>
If there are any other files that I need to update into here to show what I'm trying to do, please let me know. Thanks
Try changing your view variable name to team_numbers and replacing your team-stats.html snippet with the following:
<form method="post" action="">
<select name="teams">
{% for team_number in team_numbers %}
<option value="{{ team_number }}">Team Num: {{ team_number }}</option>
{% endfor %}
</select>
</form>
Then update your view to:
class TeamStatsView(View):
def get(self, request, *args, **kwargs):
return render(request, 'team-stats.html',
{'team_numbers':Team.objects.values('team_number')})
You can use choices=NUMBERS
NUMBERS = (
('1','1'),
('2','2'),
('3','3'),
('4','4')
)
class Team(models.Model):
team_number = models.IntegerField(choices=NUMBERS )
team_notes = models.CharField(max_length=150)
event_id = models.ForeignKey(
'Event', on_delete=models.CASCADE, unique=False)
def __unicode__(self):
return str(self.team_number)
class Meta:
db_table = 'teams'
app_label = 'frcstats'
Your view variable is called team_number.
Try to change TeamStatsView into team_number:
<form method="post" action="">
{% csrf_token %} {{ team_number }}
<input type="submit" value="Submit" />
</form>
have a form by which user can enter details about some expenses but i want to have same row in the form again and again but couldn't find out how to do that :
if you see figure above this forms works well for 1 row of data , saves well but with more then 1 row it cant . Can someone suggest any way to do that . Below are the codes :
models.py
from django.db import models
class Expenditure(models.Model):
exp_date = models.DateField("Expenditure_Date")
description = models.CharField(max_length=500)
amount = models.FloatField(default=0)
currency = models.CharField(max_length=15,default="USD")
class Meta:
unique_together = ('exp_date', 'description',)
def __unicode__(self):
return self.description
forms.py
from django import forms
from moni.models import Expenditure
from django.contrib.admin.widgets import AdminDateWidget
class ExpenditureForm(forms.ModelForm):
#exp_date = forms.DateField(help_text="Date")
exp_date = forms.DateField(widget=AdminDateWidget)
description = forms.CharField(max_length=500)
amount = forms.FloatField(initial=0)
currency = forms.CharField(widget=forms.HiddenInput(), initial="USD")
# An inline class to provide additional information on the form.
class Meta:
# Provide an association between the ModelForm and a model
model = Expenditure
fields = ('exp_date', 'amount', 'description')
views.py
from django.template import RequestContext
from django.shortcuts import render_to_response
from moni.models import Expenditure
from moni.forms import ExpenditureForm
def add_expenditure(request):
context = RequestContext(request)
if request.method == 'POST':
form = ExpenditureForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
print form.errors
else:
form = ExpenditureForm()
return render_to_response('moni/add_expenditure.html', {'form': form}, context)
add_expenditure.html
{% extends 'moni/base.html' %}
{% block title %}Add Shipment {% endblock %}
{% block body_block %}
<h1>Add a Expenditure</h1>
<p id="p_hide"> I am a paragraph to be hidden</p>
<button id ="btn1">Hide Paragraph</button>
<form id="expenditure_form" method="post" class="vDateField" action="/moni/add_expenditure/">
{% csrf_token %}
<table border=1>
<tr><th><label >Date:</label></th> <th><label for="id_description">Description:</label></th><th><label for="id_amount">Amount:</label></th></tr>
<tr><td><input class="vDateField" name="exp_date" size="10" type="text" /></td><td>{{form.description}}</td><td>{{form.amount}}<input id="id_currency" name="currency" type="hidden" value="MYR" /></td></tr>
<tr><td><input class="vDateField" name="exp_date" size="10" type="text" /></td><td>{{form.description}}</td><td>{{form.amount}}<input id="id_currency" name="currency" type="hidden" value="MYR" /></td></tr>
</table>
<input type="submit" name="submit" value="Create Expenditure" />
</form>
{% endblock %}
For that use Formeset function, Here is the idea for print form in multiple times
ExpenditureFormSet = formset_factory(ExpenditureForm, extra=3,)
And views like
if formset.is_valid():
for data in formset.cleaned_data:
And pass it into {formset} So html will print the extra 3 forms
You should use ModelFormSets instead of ModelForm.
And if you're going to add forms dynamically, use corresponding JavaScript plugin (since management form should be changed every time new form is added).