FLASK PYTHON: Submitting a flask form not working - python

I am trying to make an upload form with Flask where the user needs to fill in the information needed, upload a photo, and also pick a category provided from the database by using QuerySelectField.
When I submit the form, nothing happens. It redirects me to the same page and the database is empty.
form.py
class UploadForm(FlaskForm):
title = StringField(label='Title:', validators=[DataRequired(), Length(min=2, max=30)])
organizer = StringField(label='Name:', validators=[DataRequired(), Length(min=2, max=30)],
render_kw={'readonly': True})
type = QuerySelectField(query_factory=choice_query, allow_blank=False, get_label='name')
description = StringField(label='description',validators=[DataRequired(), Length(min=1, max=250)])
address = StringField(label='address',validators=[DataRequired(), Length(min=1, max=50)])
file = FileField(label='file', validators=[DataRequired()])
price = IntegerField(label='Price:', validators=[DataRequired(), NumberRange(min=1, max=10)])
upload = SubmitField(label='Post')
model.py
class Event(db.Model):
__tablename__ = "event"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(30), nullable=False)
price = db.Column(db.Integer(), nullable=False)
location = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(1024), nullable=True, unique=True)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
type = db.Column(db.Integer(), db.ForeignKey('category.id'), nullable=False)
image_file = db.Column(db.String(20), nullable=True, default='default.jpg')
owner = db.Column(db.Integer(), db.ForeignKey('eventowners.id'), nullable=False)
reserver = db.relationship('Reservation', foreign_keys=[Reservation.reserved_id],
backref=db.backref('reserved', lazy='joined'), lazy='dynamic',
cascade='all, delete-orphan')
class Choice(db.Model):
__tablename__ = "category"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), nullable=False)
event = db.relationship('Event', backref='events', lazy=True)
def __repr__(self):
return '[Choice {}]'.format(self.name)
class EventOwner(db.Model, UserMixin, USER):
__tablename__ = 'eventowners'
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
sub_type = db.Column(db.String, nullable=True, default=00)
events = db.relationship('Event', backref='eventowner', lazy=True)
follower = db.relationship('Follow', foreign_keys=[Follow.followed_id],
backref=db.backref('followed', lazy='joined'), lazy='dynamic',
cascade='all, delete-orphan')
routes.py
#app.route('/event/new', methods=['GET', 'POST'])
#login_required
def post_events():
if not os.path.exists('static/' + str(session.get('id'))):
os.makedirs('static/' + str(session.get('id')))
file_url = os.listdir('static/' + str(session.get('id')))
file_url = [str(session.get('id')) + "/" +
file for file in file_url]
formupload = UploadForm()
eventowner = current_user.id
formupload.organizer.data = eventowner
event = Event(owner=formupload.organizer.data)
if formupload.validate_on_submit():
event = Event(title=formupload.title.data,
type=formupload.type.data,
description=formupload.description.data,
price=formupload.price.data,
location=formupload.address.data,
image_file=photos.save(formupload.file.data,
name=str(session.get('id')) + '.jpg',))
db.session.add(event)
db.session.commit()
flash('Event Posted!')
return redirect(url_for('events_page'))
return render_template('post_event.html', formupload=formupload, event=event)
#app.route('/event', methods=['GET', 'POST'])
def events_page():
event = Event.query.order_by(Event.date_posted.desc()).all()
page = request.args.get('page', 1, type=int)
show_followed = False
if current_user.is_authenticated:
show_followed = bool(request.cookies.get('show_followed', ''))
if show_followed:
query = current_user.followed_posts
else:
query = Event.query
pagination = Event.query.order_by(Event.date_posted.desc()).paginate(page,
per_page=
current_app.config['FLASKY_POSTS_PER_PAGE'],
error_out=False
)
events = pagination.items
return render_template('event.html', events=events, pagination=pagination, show_followed=show_followed, event=event)
post_event.html
{% extends "base.html" %}
{% block content %}
<div class="breadcrumbs">
<div class="container">
<div class="row align-items-center">
<div class="col-lg-6 col-md-6 col-12">
<div class="breadcrumbs-content">
<h1 class="page-title">Events</h1>
</div>
</div>
<div class="col-lg-6 col-md-6 col-12">
<ul class="breadcrumb-nav">
<li>Home</li>
<li>Events</li>
</ul>
</div>
</div>
</div>
</div>
<form method="post" enctype="multipart/form-data" action="">
{{ form.hidden_tag() }}
<div class="search-form wow fadeInUp" data-wow-delay=".7s" style="background: none; margin-top:50px; margin-bottom:50px">
<div class="form-group">
<label for="Title" style="color: black" >Event Title</label>
{{ formupload.label }} {{ formupload.title(class='form-control' )}}
</div>
<div class="form-group col-md-6">
<label for="organizer" style="color: black" >Organizer</label>
<!-- <input type="text" class="form-control" id="Organizer"> -->
<div> {{ formupload.label }} </div>
<div> {{ formupload.organizer._value()}}</div>
</div>
<div class="form-group col-md-4">
<label for="inputState" style="color: black" >Type</label>
{{ formupload.csrf_token }}
{{ formupload.type }}
<ul>
{% for error in formupload.type.errors %}
<li style="color:red;">{{ error }}</li>
{% endfor %}
</ul>
</div>
<div class="form-group col-md-6">
<label for="description" style="color: black" >Description</label>
{{ formupload.label }} {{ formupload.description(class='form-control' )}}
<!--<input type="text" class="form-control" id="desc"> -->
</div>
<div class="form-group col-md-6">
<label for="starting_price" style="color: black" >Starting Price</label>
{{ formupload.label }} {{ formupload.price(class='form-control' )}}
<!-- <input type="text" class="form-control" id="Price"> -->
</div>
<div class="form-group">
<label for="inputAddress2" style="color: black" >Address</label>
<!-- <input type="text" class="form-control" id="Address" placeholder="Corso Duca degli Abruzzi, 24"> -->
{{ formupload.label }} {{ formupload.address(class='form-control' )}}
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck">
<label class="form-check-label" for="gridCheck" style="color: black">
I agree to the Terms of Service and Privacy Policy
</label>
</div>
</div>
<div class="form-group">
{{ formupload.file.label }}
{{ formupload.file }}
{{ formupload.upload }}
{% for file in filelist %}
<img class="upload-img" src='{{ url_for("static",filename=file) }}' alt="">
{% endfor %}
</div>
<div class="form-group">
{{ form.submit(class="btn btn--primary") }}
</div>
</div>
</form>
{% include "bottom.html" %}
<script src="{{ url_for('static',filename='js/bootstrap.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/wow.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/tiny-slider.js') }}"></script>
<script src="{{ url_for('static',filename='js/glightbox.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/main.js') }}"></script>
{% endblock %}

Unless you're submitting a form via Javascript, a form submission will get sent to the value in action attribute of the form. Yours is blank which is why the page is simply reloaded.
<form method="post" enctype="multipart/form-data" action="">
Update:
You need to specify a route in the action attribute e.g. /event/new or /event depending on which one is expected to process the form. If it's none of the above, then you have to define a route server side (your flask code) and specify the route in the action attribute.

Related

How can I display in the chat list those with whom I corresponded earlier?

I have a chat code in which I want to display and suggest only those users with whom there has already been a correspondence, that is, both incoming and outgoing messages, and not all registered users.
html code:
<div class="container" style="height: 75%;">
<div class="card bg-dark h-100 border-light">
<div class="card-body h-100">
<div class="row h-100">
<div class="col-md-4 border-right h-100">
<div class="list-group bg-dark" id='user-list'>
{% for u in users %} {% if not u.id == 1 and not u.id == user.id %}
<a class="list-group-item {% if u.id != chat_id %}bg-dark{% else %}bg-primary{% endif %} text-white" href="{% url 'chat-home' %}?u={{u.id}}">
<div>
<p>{{u.first_name}} {{u.last_name}} ({{u.username}})</p>
</div>
</a>
{% endif %} {% endfor %}
</div>
</div>
<div class="col-md-8 h-100">
{% if not chat_id > 0 %}
<div class="h-100 d-flex flex-column justify-content-center align-items-center">
<h3>Начните общение!</h3>
<p><small class="text-muted">Выберете человека, чтобы написать ему.</small></p>
</div>
{% else%}
<div id="chat-box-field" class="h-100">
<div class="chat-box" style="height:80%">
{% for chat in chats %} {% if chat.user_from == user %}
<div class="p-2 w-100 d-flex justify-content-end">
<div class=" chat-bubble ml-2 mb-2 bg-primary text-light rounded" data-id="{{chat.id}}">
<p>{{chat.message}}</p>
<div class="d-flex justify-content-between"><small>Ты</small> <small>{{chat.date_created|date:"M-d-Y H:i"}}</small></div>
</div>
</div>
{% else %}
<div class="p-2 w-100 d-flex justify-content-start">
<div class="chat-bubble mr-2 mb-2 bg-light text-dark rounded" data-id="{{chat.id}}">
<p>{{chat.message}}</p>
<div class=" d-flex justify-content-between"><small>От</small> <small>{{chat.date_created|date:"M-d-Y H:i"}}</small></div>
</div>
</div>
{% endif %} {% endfor %}
</div>
<div class="chat-box-form border-top p-2" style="height:20%">
<div class="w-100 h-100">
<form action="" id="chat-submit" class="h-100 d-flex ">
<input type="hidden" name="user_from" value="{{ user.id }}">
<input type="hidden" name="user_to" value="{{ chat_id }}">
<div class="col-md-10 h-100">
<textarea name="message" id="" class="h-100 w-100 form-control" placeholder="Написать"></textarea>
</div>
<button class="button btn btn-primary h-100 w-100 justify-content-center align-items-center d-flex">Отправить</button>
</form>
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
views.py:
def get_messages(request):
chats = chatMessages.objects.filter(Q(id__gt=request.POST['last_id']),Q(user_from=request.user.id, user_to=request.POST['chat_id']) | Q(user_from=request.POST['chat_id'], user_to=request.user.id))
new_msgs = []
for chat in list(chats):
data = {}
data['id'] = chat.id
data['user_from'] = chat.user_from.id
data['user_to'] = chat.user_to.id
data['message'] = chat.message
data['date_created'] = chat.date_created.strftime("%b-%d-%Y %H:%M")
print(data)
new_msgs.append(data)
return HttpResponse(json.dumps(new_msgs), content_type="application/json")
def send_chat(request):
resp = {}
User = get_user_model()
if request.method == 'POST':
post =request.POST
u_from = UserModel.objects.get(id=post['user_from'])
u_to = UserModel.objects.get(id=post['user_to'])
insert = chatMessages(user_from=u_from,user_to=u_to,message=post['message'])
try:
insert.save()
resp['status'] = 'success'
except Exception as ex:
resp['status'] = 'failed'
resp['mesg'] = ex
else:
resp['status'] = 'failed'
return HttpResponse(json.dumps(resp), content_type="application/json")
models.py:
class chatMessages(models.Model):
user_from = models.ForeignKey(User,
on_delete=models.CASCADE,related_name="+")
user_to = models.ForeignKey(User,
on_delete=models.CASCADE,related_name="+")
message = models.TextField()
date_created = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.message
Please tell me how it can be implemented. I don't quite understand how to set a condition for checking for messagesm
You probably need to change the related name first on the model:
class chatMessages(models.Model):
user_from = models.ForeignKey(User,
on_delete=models.CASCADE,related_name="sent")
user_to = models.ForeignKey(User,
on_delete=models.CASCADE,related_name="received")
message = models.TextField()
date_created = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.message
And then to get all messages the user has received:
messages = request.user.received.all()
(Or User.objects.get(id=my_user_id).received.all())
To get all the users which the user has corresponded with, you can then do:
pk_list = messages.values("user_from__pk").distinct()
correspondents = get_user_model().objects.filter(pk__in=list(pk_list))
Sidenote:
In your views, you are getting the user model.
User = get_user_model()
But you don't do anything with it in this view:
def send_chat(request):

Please how can get the number of listings in a category, i have tried

I have a django app and I need to count the number of listings in a category (as defined by the models below):
here is my complete model
class Category(models.Model):
name = models.CharField(max_length=500)
icon = models.ImageField(upload_to='photos/icons/%Y/%m/%d/')
def __str__ (self):
return self.name
class Listing(models.Model):
name = models.CharField(max_length=300)
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=False, null=True)
email = models.EmailField(max_length=300)
description = RichTextField(blank=False, null=False)
photo_main = models.ImageField(upload_to = 'photos/%Y/%m/%d/')
photo_1 = models.ImageField(upload_to = 'photos/%Y/%m/%d/', blank=True, default=True)
photo_2 = models.ImageField(upload_to = 'photos/%Y/%m/%d/', blank=True, default=True)
photo_3 = models.ImageField(upload_to = 'photos/%Y/%m/%d/', blank=True, default=True)
photo_4 = models.ImageField(upload_to = 'photos/%Y/%m/%d/', blank=True, default=True)
location = models.CharField(max_length=500, null=True)
phone_number = models.CharField(max_length=11, default = "#")
website = models.CharField(max_length=150, blank=True, default="#")
facebook = models.CharField(max_length=150, blank=True, default="#")
instagram = models.CharField(max_length=150, blank=True, default="#")
opening_time = models.CharField(max_length=7)
closing_time = models.CharField(max_length=7)
is_published = models.BooleanField(default=False)
posted_date = models.DateTimeField(auto_now_add=True)
user_id = models.IntegerField(blank=True)
def __str__ (self):
return self.name
here are my views
from django.shortcuts import render
from listings.models import Listing
from listings.models import Category
from testimonies.models import Testimony
from our_team.models import Team_Mate
from testimonies.models import Testimony
from django.db.models import Count
def index(request):
this part is working perfectly.
listings = Listing.objects.order_by('-posted_date').filter(is_published=True)[:6]
category = request.GET.get('category')
categories = Category.objects.all()[:7]
counting listings in a category
count_cate = Category.objects.all()
cate_count = count_cate.count()
if category == None:
listings = Listing.objects.order_by('-posted_date').filter(is_published=True)[:6]
else:
listings = Listing.objects.filter(Category__name=category)
here is my context
context ={
'listings': listings,
'categories': categories,
'cate_count': cate_count,
}
return render(request, 'pages/index.html', context)
Here is my html where I want the number of listings in category to show
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- ======= Intro Section ======= -->
<div class="header">
<div class="header-content display-table">
<div class="table-cell">
<div class="container">
<h1 class="header-title text-light text-uppercase pb-3">Explore Bonny Island</h1>
<h3 class="text-light">Find. Connect. Share</h3>
<div class="search mt-3 px-0 py-1 mx-0">
<form action="{% url 'search' %}" method="GET">
{% csrf_token %}
<div class="row d-flex justify-content-center container p-0 m-0 px-1">
<input type="text" name="keywords"
class="form-control col-lg-3 col-md-12 col-sm-12 mx-2 py-4 my-2 border border-5"
placeholder=" Keyword">
<input type="text" name="location"
class="form-control col-lg-3 col-md-12 mx-2 py-4 col-sm-12 my-2 border border-5"
placeholder=" Location">
<input type="text" name="category" value="{{ query }}" list="category"
class="form-control col-lg-3 col-md-12 col-sm-12 mx-2 py-4 my-2 border border-5"
placeholder=" Category (All)">
<datalist id="category">
{% for categories in categories %}
<option>{{ categories.name }}</option>
{% endfor %}
</datalist>
<button type="submit"
class="btn search-bt col-lg-2 col-md-12 mx-2 col-sm-12 py-2 px-2 font-weight-bold my-
2">Search</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div><!-- End Intro Section -->
<!-- ======== most popular categories ========= -->
<section class="main">
<div class="discover pb-1 m-0">
<h2>Explore Categories</h2>
<div class="container">
<div class="row justify-content-around m-0 p-0 pt-3">
{% for category in categories %}
{% if category %}
<div class="col-lg-3 col-md-6 py-2">
<a href="{% url 'listings' %}?category={{ category.name }}" class="card category">
<div class="d-flex justify-content-between align-items-start px-3 m-0 py-2">
<div class="category-name-icon p-0 m-0">
<span class="text-dark font-weight-bold"><img class="category-icon" src="{{
category.icon.url }}">
{{category.name}}</span>
</div>
<div class="category-list-number text-muted font-weight-bold">{{cate_count}}</div>
</div>
</a>
</div>
{% endif %}
{% endfor %}
<div class="col-lg-3 col-md-6 py-2">
<a href="{% url 'category' %}" class="card category" data-bs-toggle="collapse"
href="#collapseExample"
role="button" aria-expanded="false" aria-controls="collapseExample">
<div class="d-flex justify-content-between = px-3 m-0 py-2">
<i class="font-weight-bold py-1 text-secondary">More Categories...</i>
</div>
</a>
</div>
</div>
</div>
</section> <!-- ======== most popular categories end ======== -->
<!-- STRUCTURING THE POPULAR LISTINGS CONTENT-->
<section id="popularListings" class="container mb-5 py-5">
<!-- Popular listenings head title-->
<div class="sectionTitle d-flex justify-content-between align-items-baseline">
<div class="mainTitleContents">
<h2 class="titleText h2 text-blue">Popular Listings</h2>
<p class="subTitleText mb-2">Explore businesses on the island.</p>
</div>
<div class="filterOption">
All Listings
</div>
</div>
<!-- MAIN POPULAR LISTINGS ROW CONTENT-->
<div class="popularListingsRows row py-2">
{% if listings %}
{% for listing in listings %}
<div class="customCard p-1 m-0 col-lg-3 col-md-4 col-sm-6 mt-sm-3">
<div class="card">
<div class="card-header p-0">
<div class="blank rounded" style="background-image: url('{{
listing.photo_main.url }}'); background-repeat: no-repeat;
background-size:cover; width:100%; height: 15em; background-
position:center-top" ;></div>
</div>
<div class="card-body">
<div class="content-details">
<h3 class="m-0 mt-1 mb-2 cardTitle">{{ listing.name }}</h3>
<p class="cardSubTitle">
{%autoescape off%}
{{ listing.description|striptags|truncatechars:100 }}
{%endautoescape%}
</p>
<a href="{% url 'listing' listing.id %}" class="btn btn-sm bg-blue text-
light rounded-none">Read More</a>
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="col-md-12">
<p class="text-dark">No listings Available</p>
</div>
{% endif %}
</div>
</section>
{% endblock %}
How can I make this code work as intended?
You should call the count method on the list of objects like...
if category == None:
listings = Listing.objects.order_by('-posted_date').filter(is_published=True)[:6]
else:
listings = Listing.objects.filter(category__name=category).count()
Please ensure where you have Category__name=category you must allow this to match your model field category.
In your html:
<!-- ======= Intro Section ======= -->
<form action="{% url 'search' %}" method="GET">
{% csrf_token %}
<div class="row d-flex justify-content-center container p-0 m-0 px-1">
...
<!--<input type="text" name="category" value="{{ query }}" list="category" class="form-control col-lg-3 col-md-12 col-sm-12 mx-2 py-4 my-2 border border-5" placeholder=" Category (All)">-->
<!-- Remove value="{{ query }}" -->
<input type="text" name="category" list="categories" class="form-control col-lg-3 col-md-12 col-sm-12 mx-2 py-4 my-2 border border-5" placeholder=" Category (All)">
<!-- Should be category in categories instead of categories in categories -->
<datalist id="categories">
{% for category in categories %}
<option value="{{ category.name }}"> <!-- Setting the value here... -->
{% endfor %}
</datalist>
...
</div>
</form>
I solved the it by calling the name of the category i want to count but am still to look for a way to count it without specifying the category name.
cate_count = Listing.objects.filter(category__name="Catering services").count()

How to dynamically display data from a model using a button in django?

I am trying to load data from a model dynamically, the issue I am having is that I am unable to get the data dynamically, for example this is the model:
class mentee(models.Model):
application_date_time = models.DateTimeField()
full_name = models.CharField(max_length=100)
email = models.CharField(max_length=50)
phone = models.CharField(max_length=50)
gender = models.CharField(max_length=50)
university = models.CharField(max_length=500)
major = models.CharField(max_length=50)
class_standing = models.CharField(max_length=50)
city = models.CharField(max_length=50)
country = models.CharField(max_length=50)
student_type = models.CharField(max_length=50)
profile_pic = models.CharField(max_length=1000)
linkedin = models.CharField(max_length=1000)
github = models.CharField(max_length=1000)
website = models.CharField(max_length=1000)
resume = models.CharField(max_length=1000)
area_of_concentration = models.CharField(max_length=50)
roles_of_interest = models.CharField(max_length=100)
meet_in_person = models.CharField(max_length=100)
preferred_years_of_experience = models.CharField(max_length=50)
organization_of_interest = models.CharField(max_length=50)
area_of_expertise = models.CharField(max_length=100)
skills_desired = ArrayField(ArrayField(models.CharField(max_length=100)))
gender_preference = models.CharField(max_length=50)
time_preference = models.CharField(max_length=50)
location_preference = models.CharField(max_length=50)
In this function I am trying invoke is this
def showprofile(full_name):
mentee_data = mentee.objects.filter(full_name="Katha Benterman")
return mentee_data.values()
What this should do is that it should show the data in a bootstrap model which is set in the HTML like this:
<td><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">Profile</button></td>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% for profile in show_profile %}
{{ profile.full_name }}
</br>
{{ profile.email }}
</br>
{{ profile.phone }}
</br>
{{ profile.bio }}
</br>
{{ profile.gender }}
</br>
{{ profile.objectives }}
</br>
{{ profile.years_of_experience }}
</br>
{{ profile.university }}
</br>
{{ profile.graduation_year }}
</br>
{{ profile.major }}
</br>
{{ profile.class_standing }}
</br>
{{ profile.city }}
</br>
{{ profile.country }}
</br>
{{ profile.student_type }}
</br>
{{ profile.profile_pic }}
</br>
{{ profile.linkedin }}
</br>
{{ profile.GitHub }}
</br>
{{ profile.website }}
</br>
{{ profile.resume }}
</br>
{{ profile.area_of_concentration }}
</br>
{{ profile.roles_of_interest }}
</br>
{{ profile.skills_desired }}
</br>
{% endfor %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
The issue is when I statically specify a name from the full_name it will load up the data, but when I try to do it dynamically it doesn't show anything at all whatsoever, I think it may be an issue with my function and my button. Any help would be greatly appricated!
Here is the views file:
def home(request):
if request.method == 'GET':
data = mentee.objects.all()
profiles = mentee.showprofile(mentee.full_name)
mentee_data = {
"full_name": data,
"email": data,
"email": data,
"phone" : data,
"bio" : data,
"gender" : data,
"objectives" : data,
"years_of_experience" : data,
"university" : data,
"graduation_year" : data,
"major" : data,
"class_standing" : data,
"city" : data,
"country" : data,
"student_type" : data,
"profile_pic" : data,
"linkedin" : data,
"GitHub" : data,
"website" : data,
"resume" : data,
"area_of_concentration" : data,
"roles_of_interest" : data,
"skills_desired": data,
"show_profile": profiles
}
return render(request, 'main/index.html', mentee_data)

Editing data without removing previously added. Django using 'forms.Form'

How can I edit data without deleting what has been added before. In my situation, I want to use forms.Form which looks like this
class SecondForm(forms.Form):
data_1 = forms.ChoiceField(choices=CHOICES, label="")
data_2 = forms.ChoiceField(choices=CHOICES, label="")
data_3 = forms.ChoiceField(choices=CHOICES, label="")
In my views.py
id = #some object number
if request.method =="POST":
second_form = SecondForm(request.POST)
if second_form.is_valid():
cd = second_form.cleaned_data
object = Valuation(pk=object_id)
object.data_1 = cd['data_1']
object.data_2 = cd['data_2']
object.data_3 = cd['data_3']
object.save()
return HttpResponseRedirect(reverse('app:valuation_third', args=[forwarding]))
else:
second_form = SecondForm()
In this situation, if my model looks like this:
class Valuation(models.Model):
data_added_before = models.CharField(max_length=50, blank=True)
data_1 = models.CharField(max_length=50, blank=True)
data_2 = models.CharField(max_length=50, blank=True)
data_3 = models.CharField(max_length=50, blank=True)
Every time a field 'data_added_before' it's cleaned. How to avoid it. So that the information added earlier in this field has been preserved. And new data from the current form added to existing ones.
EDIT:
Any help will be appreciated.
Tempate.html
{% load crispy_forms_tags %}
<form action="." method="post">
<div class="">
<h2 class="h3 text-primary font-weight-normal mb-4">More information></h2>
</div>
{% csrf_token %}
<p>data_1 name</p>
{{ second_form.data_1|as_crispy_field }}
<p>data_2 name</p>
{{ second_form.data_2|as_crispy_field }}
<p>data_3 name</p>
{{ second_form.data_3|as_crispy_field }}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
<form>
<input class="btn btn-text btn-text-secondary" type="button" value="before" onclick="history.back()">
</form>
</div>
<div class="form-group col-md-6 mb-0">
<div class="text-right">
<button type="submit" class="btn btn-primary">next <i class="fas fa-angle-right fa-lg"></i></button>
</div>
</div>
</div>
</form>

SQLAlchemy with Flask does not commit

When I submit my form from webpage, I am not able to commit. Flashing data I need, I see they're there and correct, but something fails when committing. I am sure I am making a mistake somewhere because mostly commit are working except two. This is one of the two that is not working.
Models:
class Feedback(db.Model):
__tablename__ = 'feedback'
id = db.Column(db.Integer, primary_key = True)
rate = db.Column(db.Integer)
comment = db.Column(db.Text())
sender_id = db.Column(db.Integer)
receiver_id = db.Column(db.Integer)
Forms:
class LeaveFeedbackForm(Form):
rate = IntegerField('Rate', validators = [DataRequired(),
NumberRange(min = 1, max = 5, message = 'Rates admitted are only 1,2,3,4,5')])
comment = TextAreaField('Comment', validators = [DataRequired()])
submit = SubmitField('Submit')
Views:
#app.route('/leave_feedback/<sender>/<receiver>', methods = ['GET', 'POST'])
def leave_feedback(receiver, sender):
form = LeaveFeedbackForm()
rec = int(receiver)
sen = int(sender)
if form.validate_on_submit():
feedback = Feedback( rate = form.rate.data,
comment = form.comment.data,
receiver_id = rec,
sender_id = sen
)
db.session.add(feedback)
db.session.commit()
flash('Feedback Left Correctly.')
return redirect(url_for('index'))
flash(form.rate.data)
flash(form.comment.data)
flash(rec)
flash(sen)
return render_template('leave_feedback.html', receiver_id = receiver, sender_id = sender, form = form)
html:
{% block content %}
<div class="row">
<div class="large-6 columns">
<h1>Leave Feedback</h1>
</div>
</div>
<form action="" method="post" name="leavefeedback">
<div class="row">
<div class="large-6 columns">
<label>Rate
{{ form.rate }}
</label>
</div>
</div>
<div class="row">
<div class="large-6 columns">
<label>Comment
{{ form.comment }}
</label>
</div>
</div>
<div class="row">
<div class="large-6 columns">
<input class="button radius" type="submit" value="Leave Feedback">
</div>
</div>
</form>
{% endblock %}
You should add an else statement:
if form.validate_on_submit():
...
else:
for error in form.errors.itervalues():
flash(error[0])
Then you will get an error message from form.
I figured out my mistake, I simply forgot in my form:
{{ form.hidden_tag() }}

Categories