I am developing an angularjs app on google app engine however I have an issue displaying one of my KeyProperty fields client.
This is how the KeyProperty field is displaying (The other non KeyProperty elements are showing up fine);
NB: Post is 200 OK
model.py
class Project(ndb.Model):
projectID = ndb.IntegerProperty(required=True)
title = ndb.StringProperty(required=True)
description = ndb.StringProperty(required=True)
startAt = ndb.DateTimeProperty(indexed=True)
endAt = ndb.DateTimeProperty()
client = ndb.KeyProperty(kind='Client')
class Client(ndb.Model):
name = ndb.StringProperty()
home.html element
<div class="form-group">
<label>Client : </label>
<input type="text" ng-model="Project.Client" class="form-control"/>
</div>
In handler.py
def post(self):
r = json.loads(self.request.body)
print str(r)
cl = Client(name=r['Client']).put()
client_key = cl
g = Project(projectID=int(r['ProjectID']),
client=client_key,
description=r['Description'],
title=r['Title'],
startAt=datetime.strptime(r['StartAt'], '%Y-%m-%dT%H:%M:%S.%fZ'),
endAt=datetime.strptime(r['EndAt'], '%Y-%m-%dT%H:%M:%S.%fZ'))
project_key = g.put()
angular
eventClick: function (project) {
$scope.showSelected = true;
var fromDate = moment(project.start).format('DD/MM/YYYY LT');
var endDate = moment(project.end).format('DD/MM/YYYY LT');
$scope.Project = {
ProjectID : project.projectID,
Client : project.client,
Title : project.title,
Description: project.description,
Employees: project.employees,
StartAt : fromDate,
EndAt : endDate,
IsFullDay : false
}
$scope.ShowModal()
},
I am still learning my way to handling KeyProperties. Thanks for the help
UPDATE
This is the error I am getting when I type 'qwert' in the Client field;
I am talking about in your Python code. The error log should tell you what line of your code was expecting a string. That is where you need the .name
Related
I am developing a little app where I would like to include a button that will open outlook email editor and presented the user with an empty content but a particular subject ready to be filled in by the user and sent back to a particular email.
Does anyone know how to do that?
What I was reading in different solutions does not work:
this for instance opens a url that fails
import ipyvuetify as v
v_btn = v.Btn(class_ = 'mx-2 light-blue darken-1',
href = 'href="mailto:vinoth#email.com?subject=title&body=The message"',
children = ['send email?'])
v_btn
Other option might be to create a ipyvuetify template:
class sendemail(v.VuetifyTemplate):
subject = Unicode('').tag(sync=True)
label = Unicode('email').tag(sync=True)
template = Unicode('''<v-btn
color="primary"
class="ma-1"
#click="sendemail(subject)"
>
{{ theemail }}
</v-btn>
<script>
export default {
methods: {
sendemail (subject) {
var email = "whatever#company.org";
document.location = "mailto:" + email +"?subject=" + subject + "&body=the body";
},
},
}
</script>''').tag(sync=True)
emailitBtn = clipboardBtn(subject='This is the subject of the email', label='send email')
emailitBtn
But this solution does not work neither.
any ideas?
maybe try
import ipyvuetify as v
v_btn = v.Btn(class_ = 'mx-2 light-blue darken-1',
href = 'mailto:vinoth#email.com?subject=title&body=The message',
target = '_blank',
children = ['send email?'])
v_btn
I removed the 'href' in the href property and added target='_blank' to open it in a new Window and it seems to work.
I'm working on a project using flask and pymongo where I have a movies collection and an instance of my movies collection is like :
movie = {"title":"Hobbit" , "year":"2013"}
I have an html jinja 2 page where I submit a form and I can change the title or the year of the movie . It is not required to change both of them .
My html template :
<h1> Select a field in the movie to update </h1>
<form action = "{{url_for('execute_movie_update')}}" method = "post">
<label="update-title">Change the title</label>
<input type = "text" id="new-title" name = "new-title" >
<label="update-year"> Change year of publish </label>
<input type = "text" id = "new-year" name = "new-year">
<label="update-plot"> Change plot of movie </label>
<input type = "text" id = "new-plot" name = "new-plot">
<button type = "submit">Submit changes</button>
</form>
If I use my flask endpoint which I will include below to change both the title and the year of the movie I have in my session the update is succesful . However if I change only one field
(ex. if I change the title only the year I have is set to " " instead of being the orginal year )
I have my flask endpoint here . It updates a specific movie I have stored in a session :
#app.route('/executemovieupdate' , methods = ['GET', 'POST'])
def execute_movie_update():
if 'Email' in session and 'User' in session:
email = session['Email']
user = session['User']
if user == 'Admin':
if 'Movie' in session and 'Movie_year' in session and 'Movie_plot' in session:
movie = session['Movie']
year = session['Movie_year']
plot = session['Movie_plot']
tainia = movies.find_one({'title':movie , "year":year}) #the movie that I want to update
if request.method == 'POST':
new_title = request.form.get('new-title') #get the fields I submitted in html
new_year = request.form.get('new-year')
if new_title!=None: #if I submit only title year is set to " "
print("update the title")
movies.update_one({"title":movie , "year":year} , {"$set":{"title":new_title} } )
session['Movie'] = new_title
movie = session['Movie']
print(session)
if new_year != None: #if i submit both title and year the program works
print("update the year")
movies.update_one({"title":movie , "year":year} , {"$set": {"year":new_year}})
session['Movie_year']=new_year
year = session['Movie_year']
print(session)
return ''' movie has been updated '''
else:
return render_template('movie-update.html' , movie = tainia)
else:
return redirect(url_for('admin.html'))
else:
return redirect(url_for('login'))
else:
return redirect(url_for('login'))
I would appreciate your help in guiding me to solve this issue . Thank you in advance.
EDIT: It seems that the problem lies in my if statements as I always enter both of them even if an item is not submitted (ex. I did not submit a title )
SOLVED :
by changing title if statement to : if new_title: and year statement to if new_year:
I'm trying to integrate in my django modal an ajax call to modify directly the value of my data.
In other words I have the following views.py
class UpdateCrudUser(View):
def get(self, request):
id1 = request.GET.get('id', None)
conto1 = request.GET.get('conto', None)
obj = Materiale.objects.get(id=id1)
obj.conto = conto1
obj.save()
element = {
'id':obj.id,
'conto':obj.conto}
data = {
'element': element}
return JsonResponse(data)
After that I have build before my table as following:
{% for element in elements %}
<tr id="element-{{element.id}}">
<td class="elementConto userData" name="conto">{{element.conto}}</td>
</tr>
{% endfor %}
...
And after that the modal:
<form id="updateUser">
<div class="modal-body">
<input class="form-control" id="form-id" type="hidden" name="formId"/>
<label for="conto">Conto</label>
<input class="form-control" id="form-conto" name="formConto"/>
Finally the script with the ajax call:
function editUser(id) {
if (id) {
tr_id = $("#element-" + id);
conto = $(tr_id).find(".elementConto").text();
$('#form-id').val(id);
$('#form-conto').val(conto);
}
}
$("form#updateUser").submit(function() {
var idInput = $('input[name="formId"]').val();
var contoInput = $('input[name="formConto"]').val();
if (contoInput && tipologiaInput ) {
// Create Ajax Call
$.ajax({
url: '{% url "crud_ajax_update" %}',
data: {
'id': idInput,
'conto': contoInput,
},
dataType: 'json',
success: function (data) {
if (data.element) {
updateToUserTabel(data.element);
}
}
});
} else {
alert("Vediamo se funziona.");
}
$('form#updateUser').trigger("reset");
$('#myModal').modal('hide');
return false;
});
But If I try to modify using the modal my data, django give me the following error:
ValueError: Cannot assign "'Materia Prima'": "Materiale.conto" must be a "Conto" instance.
It's possible that this error arises from the model?Becouse conto is a foreingKey:
class Materiale(models.Model):
conto = models.ForeignKey(Conto, on_delete=models.CASCADE, null=True)
class Conto(models.Model):
nome=models.CharField('Nome Conto', max_length=30, blank=True, default="")
def __str__(self):
return self.nome
In this case how could I overcome that problem?
In your UpdateCrudUser, the variable conto1 has been assign to be a string, more precisely when you do this: conto1 = request.GET.get('conto', None).
Then, when you instantiate the Materiale model (through the obj object), you're attempting to set that string to its conto field, which expects an object of the Conto model, rather than a string.
How to overcome this? Instead of assigning that string to obj.conto directly, first make a query to get a Conto object by its field nome. Something like this in your UpdateCrudUser view:
obj = Materiale.objects.get(id=id1)
conto_obj, created = Conto.objects.get_or_create(nome=conto1)
obj.conto = conto_obj
Note that I used the get_or_create() method because in case that the user's input for Conto name doesn't match any existent object, this will create a new Conto object that then can be assign to the Materiale instance that you want to update.
I am trying to implement a function in which when I click on Activate button, the value in my Django database for this field changes to 'Active' and is displayed on the HTML page as active. If deactivate is clicked, the text changes to deactive along with it's value in the django database.
This is my current HTML page:
<div class="col-sm-5">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Job activation status</h3>
</div>
<div class="panel-body">
<b>Status</b>: Active
<span style="padding-left:20px;"></span>
<button type="button" class="btn btn-primary">Activate</button>
<button type="button" class="btn btn-primary">Deactivate</button>
<button type="button" class="btn btn-primary">Dissolve</button>
</div>
</div>
</div>
And my models.py is as follows:
class Job(models.Model):
def __unicode__(self):
return self.name
name = models.CharField('Job Name',max_length=128)
# when the job was created
date_created = models.DateTimeField('Date Created', auto_now=True)
# what entity/organization needs this job?
client_organization = models.CharField('What organization do you represent?', max_length=64)
# short description
description = models.TextField('Job Description', max_length=256)
# end product to be delivered
deliverable = models.TextField('Deliverable', max_length=256)
# when Job is due for completion
duedate = models.DateTimeField('Date Due')
# all persons who may be affected by project
#stakeholders = models.TextField('Stakeholders')
# important technical requirements
#additional_information = models.TextField('Additional Information', blank = True)
# budget estimate
#budget = models.CharField('Budget', max_length=64)
# file attachments
#attachments = models.FileField(upload_to='job', blank = True)
creator = models.ForeignKey(User,related_name = 'jobs')
organizations = models.ManyToManyField(Organization, through = 'JobRequest', blank=False, null=True)
#organizations = models.CharField(default="nothing",null=True,max_length = 256)
contact_information = models.CharField('Contact Information', max_length = 256, blank = False, null=True)
skill_required = models.CharField('Volunteer skills required', max_length=256, blank = False, null=True)
hours_day = models.CharField('Number of hours per day', max_length=256, blank = False, null=True)
# Job is closed after a jr is confirmed
closed = models.BooleanField(default = False)
# some tags to determine what organizations to submit job to
categories = models.ManyToManyField(Category, related_name = 'jobs')
#categories = models.CharField(default="nothing",null=True, max_length = 256)
status = models.IntegerField(default = 0, choices = ((0, 'Pending'), (1, 'Approved'), (2, 'Disapproved'), (3, 'Closed')))
class Meta:
permissions = (
( 'view_job','Can view Job' ),
( 'edit_job','Can edit Job'),
( 'is_creator', 'Is a creator of Job')
)
I need help in adding a field to models.py which changes according to the button click in HTML and displays active/ deactive in the HTML page according to the button clicked. I also need help in modifying the HTML page accordingly
If you need only two states (active and innactive) you need a BooleanField, so in your model you add something like this:
active = models.BooleanField(default = False)
Then, you need to create a function in your views.py to update the model in the database (I will name it ajax_change_status):
from django.http import JsonResponse
from xxx.models import Job
def ajax_change_status(request):
active = request.GET.get('active', False)
job_id = request.GET.get('job_id', False)
# first you get your Job model
job = Job.objects.get(pk=job_id)
try:
job.active = active
job.save()
return JsonResponse({"success": True})
except Exception as e:
return JsonResponse({"success": False})
return JsonResponse(data)
Then, you add the url for you ajax function in the urls.py:
url(r'^ajax/change_status/$', views.ajax_change_status, name='ajax_change_status')
and finally in you HTML, you need to call the function each time you click the button:
<script>
$("#button_id").on('click', function () {
var username = $(this).val();
var active = <true> // or false, you have to set it
var active = <id> // you have to set it
$.ajax({
url: '/ajax/validate_username/',
data: {
'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val(),
'active': active
'job_id': username
},
dataType: 'json',
success: function (data) {
if (data.success) {
alert("ajax call success.");
// here you update the HTML to change the active to innactive
}else{
alert("ajax call not success.");
}
}
});
});
</script>
finally, don't forget to put the csrf tag in you HTML:
{% csrf_token %}
I'm trying to understand how to edit or update a model. I have tried several scenarios which sometimes give an error message: 405 Method Not Allowed - The method POST is not allowed for this resource. Below is my code:
The Python Models:
import os
import webapp2
import wsgiref.handlers
from google.appengine.ext import db
from google.appengine.ext.webapp import template
class MessageModel(db.Model):
content = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
class Message(webapp2.RequestHandler):
def get(self):
doRender(self,'message.htm')
def post(self):
m = MessageModel()
m.content = self.request.get('content')
m.put()
self.redirect('/view')
class View(webapp2.RequestHandler):
def get(self):
que = db.Query(MessageModel)
messageview_list = que.fetch(999)
doRender(self,
'view.htm',
{'messageview_list': messageview_list })
class Edit(webapp2.RequestHandler):
def get(self):
doRender(self,'edit.htm')
def post(self):
updated_content = self.request.get('content')
content_query = db.GqlQuery("SELECT * "
"FROM MessageModel "
"ORDER BY date DESC LIMIT 1")
messageview_list = content_query.fetch(1)
m = MessageModel()
m.content = self.request.get(updated_content)
m.put()
doRender(self,
'edit.htm',
{'messageview_list': messageview_list })
class Main(webapp2.RequestHandler):
def get(self):
doRender(self,'index.htm')
def doRender(handler, tname = 'index.htm', values = { }):
temp = os.path.join(
os.path.dirname(__file__),
'templates/' + tname)
if not os.path.isfile(temp):
return False
newval = dict(values)
newval['path'] = handler.request.path
outstr = template.render(temp, newval)
handler.response.out.write(outstr)
return True
app = webapp2.WSGIApplication([('/', Main),
('/message', Message),
('/view', View),
('/edit', Edit)],
debug=True)
The HTML Form:
{% for messageview in messageview_list %}
<form method="post" action="/edit">
<p>
<textarea name="message" rows="3" cols="60" MAXLENGTH=60>
{{ messageview.content }}</textarea>
<br>
<input type="submit" value="Update"/>
</p>
</form>
{% ifnotequal error None %}
<p>
{{ error }}
</p>
{% endifnotequal %}
{% endfor %}
I am assuming the indentation is due to copy/paste, but make sure that the post() and get() functions are actually indented inside of your class.
In your form, you have <textarea name="message" rows="3" cols="60" MAXLENGTH=60>, but in your def post() you use updated_content = self.request.get('content'), which is looking for the content keyword in the request. Also, your edit doesn't look like it is doing what you want it to do. In order to edit an entity, the basic outline of the process is 1.) Retrieve the entity (so do as you do, query using some parameter); 2.) Modify the properties of the entity however you want; and 3.) put() the entity back in the datastore.
From your code, it looks like you are retrieving the last entity entered into the datastore, but then creating a new model instead of editing that one (assuming that is what you want to do - not quite sure if that is accurate :) ). If you are looking to modify the entity that is returned, this should work:
def post(self):
updated_content = self.request.get('message')
content_query = db.GqlQuery("SELECT * "
"FROM MessageModel "
"ORDER BY date DESC LIMIT 1")
# Your query will always return just one entity (due to the LIMIT),
# but you can use get() here instead of fetch(1)
latest_model = content_query.get()
# Update the model's content property
latest_model.content = updated_content
latest_model.put()
# Assuming you want to output that model, you'd output it now
doRender(self,
'edit.htm',
{'messageview_list': latest_model })