I am new to Google App Engine and datastore so please be patient :)
My code below is trying to ask for user inputs, either entering or deleting an entry, and the results will be shown directly in a table on the same page. When I tried to delete a particular entry in the datastore, the row does not get deleted in the datastore and sometimes new rows with empty data are added. Why does this happen?
class Events(ndb.Model):
name = ndb.StringProperty()
desc = ndb.StringProperty()
class Promote(webapp2.RequestHandler):
def get(self):
query = ndb.gql("SELECT * "
"FROM Events "
)
template_values = {"events" : query,}
template = jinja_environment.get_template('promote.htm')
self.response.out.write(template.render(template_values))
def post(self):
event = Events(name = self.request.get('name'), desc = self.request.get('desc'))
event.put()
self.redirect('/promote')
class Delete(webapp2.RequestHandler):
def post(self):
event = ndb.Key('Events', self.request.get('eventname'))
event.delete()
self.redirect('/promote')
app = webapp2.WSGIApplication([('/', Main),
('/publicsearch', PublicSearch),
('/promote', Promote),
('/delete',Delete)],
debug=True)
This is the html code
<div class="jumbotron">
<div class = "container">
<form action="/promote" method="post">
<fieldset>
<div class="row-fluid">
<p> Promote your event here! </p>
<div class="row-fluid">
<div class="span6">
<p> Name of event: <br>
<textarea class="input-block-level" name="name" rows="1" cols = "50"> </textarea></p>
<p> Event description: <br>
<textarea class="input-block-level" name="desc" rows="3" cols = "50"> </textarea></p>
<p><input type="submit" value="Submit">
</div>
</div>
</div>
</div>
</div>
<h4> Events feed </h4>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th width="30%">Name</th>
<th width="60%">Description</th>
<th>Delete Event</th>
</tr>
</thead>
<tbody>
{% for event in events %}
<tr>
<td>{{ event.name }} </td>
<td>{{ event.desc }} </td>
<td>
<form action="/delete" method="post">
<input type="hidden" name="eventkey" value="{{ event.key.urlsafe() }}">
<input type="submit" value="Delete">
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
Thanks!
The key is not based on the event name, because you haven't specified any key when creating the events: they'll just use a numeric id.
The better thing to do here would be to put the actual key in the hidden input: you can use the urlsafe method to output a string that can be used in templates.
<input type="hidden" name="eventkey" value="{{ event.key.urlsafe() }}">
and in the view:
event = ndb.Key(urlsafe=self.request.get('eventkey'))
Related
I am trying to save my form in my data base. But my code adds a new row instead of save changes to the existing one. where is my mistake?
view.py
def settings(request):
error = ''
if request.method == 'POST':
new_form = TrafficSourcesForm(request.POST)
if new_form.is_valid():
new_form.save()
else:
error = 'Something went wrong!'
new_form = TrafficSourcesForm()
forms = [TrafficSourcesForm(instance=x) for x in TrafficSources.objects.all()]
return render(request, 'mainpage/dashboard.html', {'new_form': new_form, 'forms': forms, 'error': error})
template
<div class="table table-striped table-hover">
<div class="table-row">
<th style="width: 42%">Name</th>
<th style="width: 43%">Token</th>
<th style="width: 15%">Action</th>
</div>
{% for form in forms %}
<div class="table-row">
<form method="POST">
{% csrf_token %}
<div class="table-cell">{{ form.name }}</div>
<div class="table-cell">{{ form.token }}</div>
<div class="table-cell"><button class="btn btn-lg btn-success w-100"">Save</button></div>
</form>
</div>
</div>
If its not clear: I am showing all the table from my databese on the page. I want to edit them and save again to the database.
Because you are using POST data and form to create a new instance on every request:
...
if request.method == 'POST':
new_form = TrafficSourcesForm(request.POST)
if new_form.is_valid():
new_form.save()
...
To edit an object, you first need to retrieve the instance, which is normally done using its unique identifier (pk). Although normally you would send this ID using the url dispatcher captured value. I am using a hidden field in this case:
mainpage/dashboard.html
<body>
{% if forms %}
<table class="table table-striped table-hover">
<thead>
<tr>
<th style="width: 42%">Name</th>
<th style="width: 43%">Token</th>
<th style="width: 15%">Action</th>
</tr>
</thead>
<tbody>
{% for form in forms %}
<form method="POST">
{% csrf_token %}
<tr>
<td>{{ form.name }}</td>
<td>{{ form.token }}</td>
<input type="hidden" value="{{ form.instance.pk }}" name="id">
<td class="table-cell"><button class="btn btn-lg btn-success w-100">Save</button></td>
</tr>
</form>
{% endfor %}
</tbody>
</table>
{% endif %}
<form method="POST">
{% csrf_token %}
{{new_form.as_p}}
<div class="table-cell"><button class="btn btn-lg btn-success w-100">Create</button></div>
</form>
</body>
views.py
def settings(request):
error = ''
if request.method == 'POST':
new_form = TrafficSourceForm(request.POST)
pk = request.POST.get('id')
if new_form.is_valid():
if pk:
TrafficSource.objects.filter(id=pk).update(**new_form.cleaned_data)
else:
TrafficSource.objects.create(**new_form.cleaned_data)
else:
error = 'Something went wrong!'
new_form = TrafficSourceForm()
forms = [TrafficSourceForm(instance=x) for x in TrafficSource.objects.all()]
return render(request, 'mainpage/dashboard.html', {'new_form': new_form, 'forms': forms, 'error': error})
Id recommend getting the specific object you want to modify. Ex. traffic_source = TrafficSources.objects.get(id=<id_here>)
I'm having a problem in getting the pk in my template. When I select a record it always returns the last pk ID. Btw, I'am using functional base view. Here's my collection.html:
<form method="POST" action="{% url 'single_collection' %}">
{% csrf_token %}
<table class="table" id="dataTables-example">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Status</th>
<th>Download</th>
</tr>
</thead>
<tbody>
{% for collectionlist in collection %}
<tr>
<td>{{ collectionlist.id }}</td>
<td>{{ collectionlist.sqa_name }}</td>
<td>{{ collectionlist.status }}</td>
<td class="center"><center><button type="button" class="btn btn-link" data-toggle="modal" data-target="#myModaldl{{ collectionlist.id }}" ><span class="glyphicon glyphicon-download-alt"></span></button></center></td>
</tr>
<div class="modal fade collectClass" id="myModaldl{{ collectionlist.id }}" role="dialog" tabindex="-1">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3 class="modal-title">Single Collect</h3>
</div>
<div class="modal-body form-horizontal">
<div class="form-group">
<label for="inputSQAID" class="col-sm-3 control-label">SQA Name</label>
<div class="col-sm-8">
<input type="hidden" name="pk_id" id="pk_id" value="{{ collectionlist.id }}">
<input type="text" class="form-control" name="singlecollect" value="{{ collectionlist.sqa_name }}" id="inputSQAID">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-success" name="single_dl">Download</button>
</div>
</div>
</div>
</div>
{% endfor %}
</tbody>
</table>
</form>
Here's my views.py:
def collection(request):
context = {
'collection': DataCollection.objects.all(),
'title': 'Data Collection',
}
return render(request, 'data_collection/collection.html', context)
def single_collect(request):
if request.method == 'POST':
pkid = request.POST.get('pk_id')
print(pkid)
all_data = DataCollection.objects.all()
return render(request, 'data_collection/collection.html', {'title' : 'Data Collection', 'data': all_data})
In my views.py, I just want first to print the pk ID of the item/record I selected in my table using the modal. But, it's always getting the last record in my database.
This is because you have a single <form> tag with all the DataCollection rows inside. You should have individual forms for each one, i.e.:
{% for collectionlist in collection %}
<form method="POST" action="{% url 'single_collection' %}">
{% csrf_token %}
...
</form>
{% endfor %}
I am trying to create a django based load-requirement matching web-app which takes "Load details" in a model called ShipperBoardModel where people(manufacturers) post that they want certain items to be delivered somewhere, and other people(called transporters) who bid on those posts, that they can get that job done, for their chosen price.
ShipperBoardModel
class ShipperBoardModel(models.Model):
From = models.CharField(max_length=100,null=True)
To = models.CharField(max_length=100,null=True)
Type = models.CharField(max_length=100,null=True)
Length = models.CharField(max_length=100,null=True)
Weight = models.CharField(max_length=100,null=True)
Numberoftrucks = models.IntegerField(null=True)
MaterialType = models.CharField(null=True,max_length=100)
Loadingtime = models.DateTimeField(null=True)
def _str_(self):
return self.Origin
I created the first 'loads' table where many people posted their loads on it, and this is being displayed on a page "/loads/" where it shows all active loads available for bidding.
I added a "Bid now" button next to every row, clicking on which opens a form which asks the transporters what price they are willing to bid for that particular load/task.
On clicking 'Bid now', we get a pre-filled form in a bootstrap modal relative to the row it is in. Then, a transporter enters his bid for that task/load, which I want to save into another model called 'SupplierBidModel'.
I just want to figure out how to save that bid price, into that model, along with the BidID, and the transporterID which every transporter already has when they registered.
Here is the form, followed by the model:
class SupplierBidModel(models.Model):
BidID = models.AutoField(primary_key=True)
Load_ID = models.OneToOneField(ShipperBoardModel,on_delete=models.CASCADE)
Supplier_ID = models.OneToOneField(SupplierBoardModel,on_delete=models.CASCADE)
Bid_amount = models.IntegerField(null=True)
I have some data saved in my models.py, and using that model I am rendering a table. Now, for each row I want the user to enter a single entry, which should save that data into another model.
Here is the template :
{% block content %}
<table>
{% for item in data %}
<tr>
<th>From</th>
<th>To</th>
<th>Weight</th>
<th>Length</th>
<th>Type</th>
<th>Material Type</th>
<th>Number of Trucks</th>
<th>Loading Time</th>
</tr>
<tr>
<td>{{ item.From }}</td>
<td>{{ item.To }}</td>
<td>{{ item.Weight }}</td>
<td>{{ item.Length }}</td>
<td>{{ item.Type }}</td>
<td>{{ item.MaterialType }}</td>
<td>{{ item.Numberoftrucks }}</td>
<td>{{ item.Loadingtime }}</td>
<td>
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal{{ item.id }}">Bid
now! for id {{ item.id }} </button>
</td>
{# {% endfor %}#}
<div class="modal fade" id="myModal{{ item.id }}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<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>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.To }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.From }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Weight }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Length }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Type }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.MaterialType }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Numberoftrucks }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Loadingtime }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here...">Bid
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</tr>
{% endfor %}
</table>
{% endblock %}
I do not yet know how to render a form, on a page in django, where there exists a form already. The only way to render form I know of, is using the urls.py method :
urlpatterns = [
url(r'supplier', views.supplierboardfun, name='supplierboard'),
url(r'shipper', views.shipperboardfun, name='shipperboard'),
url(r'loads', views.suppliertablefun, name='supplierboardtable')
]
which calls the function suppliertablefun()
def suppliertablefun(request): # function to display shipperboardmodel
data = ShipperBoardModel.objects.all()
return render(request, 'supplierboard/board.html', locals())
I am probably missing on how to render a multiple forms with different models in django, or how to save data from an input box, and save it to the model of my liking along with some relative information.
I figured it out. I was able to do it as such
def suppliertablefun(request): # function to display shipperboardmodel
data = ShipperBoardModel.objects.all()
if request.method == 'POST':
forminput = BiddingForm(request.POST)
if forminput.is_valid():
forminput.save()
forminput = BiddingForm(request.POST)
return render(request, 'supplierboard/board.html', locals(),{'forminput': forminput})
I'm making different sized tables base off a given list and it is generated via a for loop with flask in HTML. The issue that I am having is that I'm not sure how to retrieve the values that are being entered into the type="number" form. Here is an example of my code.
HTML code:
<table>
<tr>
<th><h1>Name</h1></th>
<th><h1>Number</h1></th>
</tr>
{% for i in range(names|length) %}
<tr>
<td><h2>{{ names[i] }}</h2></td>
<td><form>
<input type="number" name="{{ i }}" placeholder="0" step="1" min="0" max="10" formmethod="post">
</form></td>
<td><form>
<input type="submit" class="btn" name="save_button" value="Save" formmethod="post">
</form></td>
</tr>
{% endfor %}
</table>
Flask code:
#app.route('/', methods=['GET', 'POST'])
def phone():
names = ['Jacob', 'Joe', 'Billy', 'Sue', 'Sally']
if request.form.get('save_button'):
for name in names:
print(request.form.get('name')
return render_template('phone.html', names=names)
The only thing returned is "None." Any help is greatly appreciated.
try request.form.get("0")
its because your inputs name is not "name" so there is no value in request.form.get("name")
<input type="number" name="{{ i }}" placeholder="0" step="1" min="0" max="10" formmethod="post">
sets the name to whatever i is (ie a value from 0..N)..,
I have retrieved data from the database and displayed it in a table. Now click of EDIT button I want to edit the form.i have sucessfully insert and retrived data from the database but i cant understand how to edit and save into database.
viwes.py
def pramod(request):
p1 = request.POST.get('name',' ')
p2 = request.POST.get('address',' ')
p3 = request.POST.get('city',' ')
p4 = request.POST.get('sp',' ')
p5 = request.POST.get('country',' ')
p6 = request.POST.getlist('chk1[]',' ')
p7 = request.POST.get('sex',' ')
books = Publisher(name=p1,address=p2,city=p3,state_province=p4,country=p5,course=p6,Gender=p7)
books.save()
dataset=Publisher.objects.all()
data={
'dataset':dataset,
}
return render(request,'Publisher.html',data)
models.py
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
course = models.CharField(max_length=50)
Gender = models.CharField(max_length=50)
Publisher.html
<div class="col-lg-4" style="margin-top: 100px">
<form action="/pramod/" method="POST">
{% csrf_token %}
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" />
</div>
<div class="form-group">
<label>Address</label>
<input type="text" name="address" class="form-control" />
</div>
<div class="form-group">
<label>city</label>
<input type="text" name="city" class="form-control" />
</div>
<div class="form-group">
<label>state_province</label>
<input type="text" name="sp" class="form-control" />
</div>
<div class="form-group">
<label>country</label>
<input type="text" name="country" class="form-control" />
</div>
<div class="form-group">
<label>Course</label>
<input type="checkbox" name="chk1[]" value="Dot.NET" > Dot.NET
<input type="checkbox" name="chk1[]" value="Python" > Python
<input type="checkbox" name="chk1[]" value="Django" > Django
</div>
<div class="form-group">
<label>Sex</label>
<input type="radio" name="sex" checked="checked" value="Male" >Male
<input type="radio" name="sex" checked="checked" value="Female" >Female
</div>
<button type="submit" class="btn bg-olive btn-block">save</button>
</form>
</div>
<div class="col-lg-8" style="margin-top: 100px">
<table class="table table-striped table-condensed table-bordered ">
<B class="btn-success">Data</B> <thead class="btn-primary">
<tr>
<th>Name</th>
<th>Address</th>
<th>city</th>
<th>country</th>
</tr>
</thead>
<tbody>
{% for p1 in dataset %}
<tr>
<td>{{ p1.name }}</td>
<td >{{ p1.address }}</td>
<td >{{ p1.city }}</td>
<td >{{ p1.country }}</td>
<td>edit</td>
<td><a>Delete</a></td>
</tr>
{% endfor %}
</tbody>
</table>
Looking from your code, it looks like a very raw code where you are trying to do everything yourself.
You can try out either of following, to solve this issue:
A. Class Based views (UpdateView):
In Django, Class Based views have been introduced which are highly preferred over function based views.
So, the functionality you are coding above can easily be Achieved using UpdateView in Django: https://docs.djangoproject.com/en/1.6/ref/class-based-views/generic-editing/#updateview
B. Model Forms in Django:
But, If you don't want to change the current view, then you should try Django ModelForms: https://docs.djangoproject.com/en/1.6/topics/forms/modelforms/
Here is a sample use of Model forms: http://www.pythoncentral.io/using-python-django-modelform-first-django-application/
I would highly recommend you use UpdateView, because it already uses a ModelForm behind the scene