I have related model EntertainmentCollage with image fields and did't now how to transfer instance models to the editing form. I need to display the existing images in the editing form and have the ability to add new ones.
models.py
class Entertainment(models.Model):
main_photo = models.ImageField(upload_to = 'where/')
place = models.CharField(max_length=200)
description = models.CharField(max_length=200)
event_date = models.DateTimeField(auto_now_add=False, blank=True, null = True)
class EntertainmentCollage(models.Model):
img = models.ImageField(upload_to = 'entertainment/portfolio', blank = True)
album = models.ForeignKey(Entertainment, blank = True, null = True)
views.py
def edit_where(request, pk):
place = Entertainment.objects.get(id=pk)
FormSet2 = inlineformset_factory(Entertainment, EntertainmentCollage, fields =['img',], extra=6)
form = WhereCreateForm(instance=place)
form2 = FormSet2()
if request.user.is_authenticated():
if request.method == "POST":
form = WhereCreateForm(request.POST, request.FILES, instance=place)
if form.is_valid():
form2 = FormSet2(request.POST or None, request.FILES)
if form2.is_valid():
form.save()
form2.save()
return redirect('entertainment:where_list')
else:
form = WhereCreateForm()
form2 = FormSet2()
return render(request, "entertainment/where_edit.html", {'form': form, 'form2': form2})
html
<section>
<div class="container">
<div class="row">
<div class="col-md-3">
<h2>Editing Where</h2>
<br>
<form method = "post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.eventname }}</p>
<p>{{ form.place }}</p>
<p>{{ form.event_date }}</p>
</div>
<div class="col-md-9">
<section class="admin-section">
{{ form2.management_form }}
<div class="row">
{% for frm in form2 %}
<div class="col-md-4 admin__block" is-cover="false">
<div class="cover__wrapper edit__wrapper">
<a class="delete-button">Delete</a>
<a class="make-cover-button">Cover</a>
<img src="{{ frm.url }}" alt="">
</div>
</div>
{% endfor %}
</div>
Add photo
</section>
<section>
<h4>Description</h4>
{{ form.description }}
<input type="submit" value="Save">
Cancel
</section>
</form>
</div>
</div>
</div>
</section>
If I try to add
collage = EntertainmentCollage.objects.filter(album = place)
to my views.py and make form2(instance = collage) error occured QuerySet' object has no attribute 'pk'
___ UPDATE ___
I need to get page like http://joxi.ru/Dr8X8w4tkGw1zr
where images are taken from the model EntertainmentCollage,
and if they are added then I could see them in the form.
I realized that my question was incorrectly asked. I just had to display all the images from the queryset and use the inline form to add a button to add a new image.
Related
I have a problem using Django forms while learning Django and adapting code from a variety of online courses and examples. As a result, the code may be “messy” – but if I can get it to work the way I need, I can improve my coding style later.
I wish to display a template that contains a form. Some of the data displayed in the page rendered in the template is read from one table/model, polls_CC_Questions, and I wish to write data input in the page into a related table, polls_CC_Resp_NoFK.
The models used are:
class CC_Questions(models.Model):
q_text = models.CharField('Question text', max_length=200)
C1_Type = models.CharField('Choice 1 Type', max_length=2)
Choice1_text = models.CharField('Choice 1 text', max_length=100)
C2_Type = models.CharField('Choice 2 Type', max_length=2)
Choice2_text = models.CharField('Choice 2 text', max_length=100)
#
def __str__(self):
return self.q_text[:20]
class CC_Resp_NoFK(models.Model):
Person_ID = models.IntegerField()
Test_date = models.DateTimeField('date test taken')
Q_ID = models.IntegerField()
Response_value = models.IntegerField(default=0,
validators=[MaxValueValidator(100), MinValueValidator(-100)])
#
def __str__(self):
return self.Person_ID
Now I can display the template containing valid data when I enter the url:
http://localhost:8000/polls/p2vote/4/
This is processed in urls.py
app_name = 'polls'
urlpatterns = [
…..
……
# ex: /polls/p2vote/<q_id>
path('p2vote/<int:q_id>/', p2_views.p2vote, name='p2vote'),
…..
The views.py entry that is used:
def p2vote(request,q_id):
#next line has been copied from CC_quest view to GET Question data
CC_question = get_object_or_404(CC_Questions, pk=q_id)
#
if request.method == 'POST':
form = VoteForm(request.POST)
if form.is_valid():
form.save()
return redirect('/polls/p2')
else:
formV = VoteForm()
#context = {'form' : formV}
return render(request, 'pollapp2/vote.html', {'var_name':CC_question,'form' : VoteForm()})
in forms.py
class VoteForm(forms.ModelForm):
class Meta:
model = CC_Resp_NoFK
fields = ['Person_ID', 'Test_date', 'Q_ID','Response_value']
The template launched, uses data from the polls_CC_Questions model/table to create the labels of the input field. This works fine so my displayed page
http://localhost:8000/polls/p2vote/5/
Displays data from the CC_Questions table, “carried in the variable varname” what the questions and their choices are. For example, the template displays the contents of {{ var_name.q_text }} and {{ var_name.Choice1_text }} , see below
Also, the page displayed containing the ModelForm is correctly displayed with labels. The template used :
<!-- vote.html based on create.html -->
<!-- 2022-02-17
Change text on page
Extracted data from CC_Question record passed as varname
-->
{% extends "pollapp2/base.html" %}
<!-- load widget tools to give me more control over layout of form in template -->
{% load widget_tweaks %}
<!-- block Title is the name in the tab -->
{% block title %}Vote on Question{% endblock %}
{% block main %}
<div class="row">
<div class="col-lg-10 col-lg-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Select one from two choices</h3>
</div>
<form method="POST">
{% csrf_token %}
<div class="panel-body">
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<label for="question">Question to answer</label>
{{ var_name.q_text }}
</div>
</div>
</div>
<div class="row">
<div class="col-lg-5">
<div class="form-group">
<label for="Choice1_text ">Choice 1</label>
{{ var_name.Choice1_text }}
</div>
</div>
<div class="col-lg-5">
<div class="form-group">
<label for="option2">Choice 2</label>
{{ var_name.Choice2_text }}
</div>
</div>
</div>
<!-- Attempt at Input fields follow -->
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<label for="Person_id">Person ID</label>
{% render_field form.Person_ID rows="1" class="form-control" %}<br>
<label for="Test_date">Test Date</label>
{% render_field form.Test_date rows="1" class="form-control" %}<br>
<label for="Q_ID">Question ID</label>
{% render_field form.Q_ID rows="1" class="form-control" %} <br>
<label for="Response_value">Response value</label>
{% render_field form.Response_value rows="1" class="form-control" %}
</div>
</div>
</div>
<div class="row">
<hr />
<div class="col-lg-4">
<button type="submit" class="btn btn-info">Submit</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
To summarise. All the above “works” in the sense a page is displayed when url : http://localhost:8000/polls/p2vote/X/ is entered in the browser and “X” is the id of the question , extracting data from the model: CC_questions. Also, on the page are input boxes created by the form, VoteForm, that allow data to be entered into table/model CC_Resp_noFK.
However, what I want to do is NOT offer Q_ID as an input field in the page, but instead populate it with the value from variable {{ var_name.id }}. I can’t work out whether I need to modify the vote.html template in some way, particularly the line:
<label for="Q_ID">Question ID</label>
{% render_field form.Q_ID rows="1" class="form-control" %} << change this ??
or the view, somewhere around form.save() ??
def p2vote(request,q_id):
#next line has been copied from CC_quest view to get Question data
CC_question = get_object_or_404(CC_Questions, pk=q_id)
#
if request.method == 'POST':
form = VoteForm(request.POST)
if form.is_valid():
form.save() << Somewhere around here ??
return redirect('/polls/p2')
else:
formV = VoteForm()
#context = {'form' : formV}
# return render(request, 'pollapp2/vote.html', context)
# following return tries to send question record into vote.html template
return render(request, 'pollapp2/vote.html', {'var_name':CC_question,'form' : VoteForm()})
Step 1: Delete Q_ID from VoteForm.
class VoteForm(forms.ModelForm):
class Meta:
model = CC_Resp_NoFK
fields = ['Person_ID', 'Test_date', 'Response_value']
Step 2: Add Q_ID after check if the form is valid and before save the object.
def p2vote(request,q_id):
#next line has been copied from CC_quest view to get Question data
CC_question = get_object_or_404(CC_Questions, pk=q_id)
if request.method == 'POST':
form = VoteForm(request.POST)
if form.is_valid():
item = form.save(commit=False)
item.Q_ID = q_id
item.save()
return redirect('/polls/p2')
I have an image upload function in django. However, images cannot be uploaded. The page is redirected to successURL. I don't understand the cause.
The view is current because it uses multiple forms.
#view
def UserEdit(request):
if request.method == 'POST':
form = forms.UserUpdateForm(request.POST, instance=request.user)
subform = forms.ProfileUpdateForm(request.POST, instance=request.user.profile)
if all([form.is_valid(), subform.is_valid()]):
user = form.save()
profile = subform.save()
return redirect('person:myaccount', username=request.user)
else:
form = forms.UserUpdateForm(instance=request.user)
subform = forms.ProfileUpdateForm(instance=request.user.profile)
return render(request, 'accounts/accounts_edit.html', {
'form': form,
'subform': subform,
})
#form
class UserUpdateForm(forms.ModelForm):
#...
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = profile
fields = ('first_name','last_name','birthday','image',)
#model
class profile(models.Model):
image = models.ImageField(upload_to='profile/',default='profile/default.jpg')
#html
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="text-center col-lg-6 col-md-6 col-sm-10 mx-auto">
<div class="form-group">
{{ form }}
</div>
<div class="form-group">
{{ subform }}
</div>
<button type="submit" class="fadeIn fourth btn btn-light">Submit</button>
</div>
</form>
I have a model with Usuario where the profile foto goes and it saves perfectly in the database, so to be able to add more images as if it were a gallery, I created another model called Gallery, I copied the same specificiation of what was already working in the model Usuario, however he is not saving the photos in the database, and I do not know where I am going wrong.
I appreciate any help.
and I need the Gallery model to receive the foreign Usuario key
Erro:
IntegrityError at /gallery-novo/
null value in column "usuario_id_id" violates not-null constraint
DETAIL: Failing row contains (3, IMG_20180622_101716179_BURST006.jpg, eu e meu amor, null).
views.py
def gallery(request):
gallery = Gallery.objects.all()
form = GalleryForm()
data = {'gallery': gallery, 'form': form}
return render(request, 'gallery.html', data)
def gallery_novo(request):
if request.method == 'POST':
form = GalleryForm(request.POST, request.FILES)
if form.is_valid():
form.save(user=request.user)
return redirect('sistema_perfil')
else:
form = GalleryForm
return render(request, 'gallery.html', {'form': form})
models.py
class Gallery(models.Model):
gallery = StdImageField( blank=False, variations={
'large': (600, 400),
'thumbnail': (100, 100, True),
'medium': (300, 200),
})
titulo = models.CharField(max_length=50, blank=False)
usuario_id = models.ForeignKey(User, on_delete=models.CASCADE, blank=False)
forms.py
class GalleryForm(forms.ModelForm):
gallery = forms.FileField(
widget=forms.ClearableFileInput(attrs={'multiple': 'True'}))
titulo = forms.CharField()
class Meta:
model = Gallery
fields = ( 'gallery', 'titulo')
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
return super(GalleryForm, self).__init__(*args, **kwargs)
def save(self, commit=True, user=None):
form = super(GalleryForm, self).save(commit=False)
form.usario_id = user
if commit:
form.save()
return form
gallery.html
{%extends 'bases/base.html' %}
{% load static %}
{% load bootstrap %}
{% load widget_tweaks %}
{% load crispy_forms_tags %}
{% block main %}
<div class="card text-white bg-primary">
<div class="card-header"><p class="card-text">
<small class="text-muted">
Home /
<a class="text-white">Cadastro</a>
</small></a></p> Cadastro de Usúario
</div>
<div class="card title ">
<div class="card-body text-secondary">
<form class="exampleone" action="{% url 'sistema_gallery_novo' %}" method="POST" enctype="multipart/form-data" id="form" name="form" validate >
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-4">
{{ form.gallery | as_crispy_field }}
</div>
<div class="form-group col-md-4">
{{ form.titulo | as_crispy_field }}
</div>
<div class="form-group col-md-4">
</div>
</div>
</div>
<button type="submit" class="btn btn-primary btn-block">Cadastrar</button>
</form>
</div>
</div>
</div>
{% endblock %}
{% block rightcol %}
{% include 'bases/rightcol.html' %}
{% endblock %}
{% block footer %}
{% include 'bases/footer.html' %}
{% endblock %}
urls.py
url(r'gallery/$', gallery, name='sistema_gallery'),
url(r'gallery-novo/$', gallery_novo, name='sistema_gallery_novo'),
In my opinion, you are reinventing the wheel, the django right approach is to use commit=False on save method:
def gallery_novo(request):
if request.method == 'POST':
form = GalleryForm(request.POST, request.FILES)
if form.is_valid():
my_novo_gallery = form.save(commit=False) #save no commit
my_novo_gallery.user=request.user #set user
my_novo_gallery.save() #save to db
return redirect('sistema_perfil')
I am trying to display a pdf file in an html template and also be able to update that pdf file, I read the tutorials on how to display a pdf file but I'm not sure why mine isn't really working, I have a model called Reference
class References(models.Model):
REFERENCE_MATERIAL = (
('seating', 'Seating Plan'),
('organization', 'Organization Chart')
)
# the variable associated with the reference
reference_name = models.CharField(max_length=100, choices=REFERENCE_MATERIAL,)
reference_file = models.FileField(null=True, blank=True, upload_to='references/')
date_updated = models.DateField(auto_now=True)
# on submit click of update entry page, it redirects to the url below.
def get_absolute_url(self):
return reverse('references-home')
Here are the views to update a reference and the one that displays it
class SeatingReferenceView(generic.ListView):
context_object_name = 'seating_plan'
template_name = 'catalog/references-seating.html'
def get_queryset(self):
return References.objects.filter(reference_name='seating').order_by('date_updated').first()
def reference_update(request):
if request.method == 'POST':
form = UploadReference(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('references-home')
else:
form = UploadReference()
return render(request, 'catalog/references_update.html', {'form': form,})
Here is my template
<div class="container maintenance-container">
<div class="row" >
<div class="maintenance-title">
<h1 class="mainrow">Seating Plan</h1>
<h4 class="maintenance-under">Seating Plan for Kitchener Floor 1</h4>
</div>
</div>
<div class="row">
{% if seating_plan %}
<div class="col-lg-12">
{{ seating_plan.read }}
</div>
{% else %}
<div class="col-lg-12">
<div class="mainpanelcontent">
<h4>There are no seating plans to display</h4>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}
However I'm receiving nothing in my html template, I am storing my files in a folder under /media/references, I can see the files are in there currently and I can see in my database that under the reference_file column that there are files called seatingplan.pdf but still nothing is showing. Thank you !
I am trying to fill out a form in my Django web application and post it. It is giving me an error
object Application has no attribute cleaned_data
I looked around Stack Overflow at similar questions, but the resolutions for others are not issues with my code. Here is my view:
def single_career(request, a_slug):
a_slug = a_slug.strip('/')
try:
career = Career.objects.get(slug=a_slug)
except:
career = None
if request.method == "POST":
form = Application(request.POST, request.FILES)
Post = True
if form.is_valid():
cleaned_data = Application.cleaned_data
is_valid = True
clean_first = cleaned_data['first_name']
clean_last = cleaned_data['last_name']
clean_email = cleaned_data['email']
clean_phone = cleaned_data['phone']
clean_file = cleaned_data['resume']
clean_message = cleaned_data['message']
date = datetime.datetime.now()
else:
is_valid = False
else:
form = Application()
Post = False
is_valid = False
context = {'career': career, 'form': form, 'post': Post, 'is_valid': is_valid}
template = 'overrides/careers.html'
set_detail_context(request, context)
return render_to_response(template, context, context_instance=RequestContext(request))
the html:
<form action="" method="POST" enctype="multipart/form-data" class="application-form">
{% csrf_token %}
<div class="firstname">
<p>FIRST NAME</p>
{{ form.first_name }}
</div>
<div class="lastname">
<p>LAST NAME</p>
{{ form.last_name }}
</div>
<div class="email">
<p>EMAIL</p>
{{ form.email }}
</div>
<div class="phone">
<p>PHONE</p>
{{ form.phone }}
</div>
{# form fileupload-input is hidden, and extra readonly text-input is there #}
{# to be able to override the styling of the fileupload-input button #}
<div>
<p>ATATCH PDF RESUME</p>
<input class="readonly" type="text" READONLY>
<div class="resume">
{{ form.resume }}
<div>
<a id="browse">BROWSE</a>
</div>
</div>
</div>
<div>
<p>MESSAGE</p>
{{ form.message }}
</div>
<button class="submit-button" type="submit">
APPLY
</button>
</form>
and the form class:
from django import forms
class Application(forms.Form):
first_name = forms.CharField(label="First Name", max_length=50)
last_name = forms.CharField(label="Last Name", max_length=50)
email = forms.EmailField(label="Email", max_length=80)
phone = forms.CharField(label="Phone Number", max_length=30)
resume = forms.FileField(label="Resume", max_length=1000)
message = forms.CharField(label="Message", max_length=800, widget=forms.Textarea)
The validated form is form, not Application.
The cleaned_data belongs to the form instance. You should have:
if form.is_valid():
cleaned_data = form.cleaned_data
You are getting the error because you are trying to fetch it from the form class.
if form.is_valid():
cleaned_data = Application.cleaned_data