Dynamically choose which properties to write to Appengine Datastore - database

Has anyone tried to dynamically select which properties they want to write to an entity on appengine? For example:
I have a web form with 5 fields, and any given user will fill out some subset of those fields. I POST only the fields with data to the server (e.g. Fields 1,2,4). On the server side, how do I elegantly write only properties 1,2, and 4? The Model class has a function that returns a dictionary of property names (Model.properties()), but how would I use it to select property names?
In SQL, I would build an INSERT or UPDATE statement by matching the fields POSTed against the Model.properties() dictionary. I would look at the db module code in the Appengine SDK, to see if the Model class had some collection of Property objects, but I can't find the module on my disk (I'm a little new to python and appengine).
Update: I read trunk/google/appengine/ext/db/init.py which confirmed that there is no way to refer to the properties as a group. Anyone know of a workaround?
Any thoughts?
Update2: This question was answered on the Google Group for AppEngine: http://groups.google.com/group/google-appengine/browse_thread/thread/b50be862f6d94b6e#

The python module will look something like this:
from google.appengine.ext.db import Key
from google.appengine.api.datastore import Get, Put
def edit_item(request, db_id):
objKey = Key(str(db_id))
if request.method == 'POST':
objEntity = Get(objKey)
for k, v in request.POST.iteritems():
objEntity[k]=v
Put(objEntity)
return HttpResponseRedirect('/')
query = TestModel.get(objKey)
return render_to_response('edit.html', ({'modify_data': query,}))
Your HTML should look something like this:
<form method="POST" action="." enctype="multipart/form-data">
Title: <input type="text" name="title" value="{{modify_data.field1}}"/>
Text: <input type="text" name="txt" value="{{modify_data.field2}}"/>
<input type="submit"/>
</form>

Related

Wordpress addon to add data to a database and then call the data

I know this question is probably going to get downvoted and I will probably get into trouble but I am hoping someone may be able to help me with my situation.
On my site I use json to download data from an external source, and then I style it beautifully.
Within the json data is an individual ID for each data set.
What I want to accomplish is to have a database where I can insert the ID and a url link.
I have created the table within the wordpress database via phpMyAdmin, but I want to create a page within the admin section where I can simply add the data in.
For displaying the json data I use a php insert addon, within that php clip i want to do a piece of code that checks the database for the id within my custom database and displays the link.
I will be honest I don't know where to start on this, even if its just a link to a source that shows me how to create an admin page and submit data to the database within wordpress dashboard.
I really appreciate any help given and like I say I know I should try harder, but when ever I do a search all I get is 100's of references to add an admin to the database manually.
Thanks,
Adam
Edit I just realized I never put any table information in my question.
The table name within wordpress is called: wp_home_tickets
within that are 3 fields: id (auto increasement), gameid (numeric) and ticketlink (text)
thanks.
For adding a custom settings page in your admin, use the Settings API https://codex.wordpress.org/Settings_API
Here is a nice tutorial using it https://deliciousbrains.com/create-wordpress-plugin-settings-page/#wp-settings-api
To fetch data from your custom table, use the wpdb class https://developer.wordpress.org/reference/classes/wpdb/. More specifically, you can use wpdb::get_results if you will have multiple rows sharing the same id https://developer.wordpress.org/reference/classes/wpdb/get_results/
Or wpdb::get_row if you will ever only have one https://developer.wordpress.org/reference/classes/wpdb/get_row/
Hope this helps you out!
For anyone wishing to see how it was done, here is how I did it.
I created a file in my theme called db_admin_menu.php and added the following to it:
<?php
function ticket_admin_menu() {
global $team_page;
add_menu_page( __( 'Tickets', 'sports-bench' ), __( 'Tickets', 'sports-bench' ), 'edit_posts', 'add_data', 'ticket_page_handler', 'dashicons-groups', 6 ) ;
}
add_action( 'admin_menu', 'ticket_admin_menu' );
function ticket_page_handler() {
$table_name = 'wp_home_tickets';
global $wpdb;
echo '<form method="POST" action="?page=add_data">
<label>Team ID: </label><input type="text" name="gameid" /><br />
<label>Ticket Link: </label><input type="text" name="ticketlink" /><br />
<input type="submit" value="submit" />
</form>';
$default = array(
'gameid' => '',
'ticketlink' => '',
);
$item = shortcode_atts( $default, $_REQUEST );
$gameid = $item['gameid'];
if ($wpdb->get_var("SELECT * FROM wp_home_tickets WHERE gameid = $gameid ")) { echo 'Ticket already exists for this game.'; goto skip; }
if (!empty($_POST)) { $wpdb->insert( $table_name, $item ); }
skip:
}
?>
I then put this code in my script that fetches and displays the json:
$matchid = $match['id'];
$ticket_url = $wpdb->get_var("SELECT ticketlink FROM wp_home_tickets WHERE gameid = '$matchid' ");
if ($ticket_url) { echo 'Get Tickets'; }
I hope someone does find it of use, i did have to use a wordpress plugin called `Insert PHP Code Snippet' by xyzscripts to be able to snippet the php to a shortcode, but that is not the purpose of this post.
Thanks again for your help.

How to prevent duplicates when using ModelChoiceFilter in Django Filter and Wagtail

I am trying to use filters with a Wagtail Page model and a Orderable model. But I get duplicates in my filter now. How can I solve something like this?
My code:
class FieldPosition(Orderable):
page = ParentalKey('PlayerDetailPage', on_delete=models.CASCADE, related_name='field_position_relationship')
field_position = models.CharField(max_length=3, choices=FIELD_POSITION_CHOICES, null=True)
panels = [
FieldPanel('field_position')
]
def __str__(self):
return self.get_field_position_display()
class PlayerDetailPage(Page):
content_panels = Page.content_panels + [
InlinePanel('field_position_relationship', label="Field position", max_num=3),
]
class PlayerDetailPageFilter(FilterSet):
field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.all())
class Meta:
model = PlayerDetailPage
fields = []
So what I am trying to do is create a filter which uses the entries from FIELD_POSITION_CHOICES to filter out any page that has this position declared in the inline panel in Wagtail.
As you can see in the picture down below, the filters are coming through and the page is being rendered. (These are 2 pages with a list of 3 field positions).
So Page 1 and Page 2 both have a "Left Winger" entry, so this is double in the dropdown. The filtering works perfectly fine.
What can I do to prevent this?
The solution should be something like this (Credits to Harris for this):
I basically have one FieldPosition object per page-field position, so it's listing all of the objects correctly. I suspect I should not use the model chooser there, but a list of the hard coded values in FIELD_POSITION_CHOICES and then a filter to execute a query that looks something like PlayerDetailPage.objects.filter(field_position_relationship__field_position=str_field_position_choice). But what is the Django Filter way of doing this?
Raf
In my limited simplistic view it looks like
class PlayerDetailPageFilter(FilterSet):
field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.all())
is going to return all the objects from FieldPosition and if you have 2 entries for 'left wing' in here (one for page 1 and one for page 2) then it would make sense that this is duplicating in your list. So have you tried to filter this list queryset with a .distinct? Perhaps something like
class PlayerDetailPageFilter(FilterSet):
field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.values('field_position').distinct())
I found the solution after some trial and error:
The filter:
class PlayerDetailPageFilter(FilterSet):
field_position_relationship__field_position = filters.ChoiceFilter(choices=FIELD_POSITION_CHOICES)
class Meta:
model = PlayerDetailPage
fields = []
And then the view just like this:
context['filter_page'] = PlayerDetailPageFilter(request.GET, queryset=PlayerDetailPage.objects.all()
By accessing the field_position through the related name of the ParentalKey field_position_relationship with __.
Then using the Django Filter ChoiceFilter I get all the hard-coded entries now from the choice list and compare them against the entries inside the PlayerDetailPage query set.
In the template I can get the list using the Django Filter method and then just looping through the query set:
<form action="" method="get">
{{ filter_page.form.as_p }}
<input type="submit" />
</form>
{% for obj in filter_page.qs %}
{{ obj }} >
{% endfor %}

How to Upload png file to database using url?

hi fellow programmers I am new in web programming, I have a task that I need to upload png files to sql database using url.
$connection = mysqli_connect ($db_host,$db_user,$db_pass);
mysqli_select_db($connection,$db_name);
$sql1 = "INSERT INTO figures (Id, Name, Image) VALUES ('".$_GET['id']."', '".$_GET['Name']."', '".$_GET['Image']."')";
mysqli_query($connection,$sql1);
Those lines used to send data , in this way I can upload VARCHAR to the database how ever I cannot upload png ,I don't know how to define file path here. (Maybe if you know easier solution for my task, could you please share it? )
Thanks in advance!!
First of all you need to set the sending form to multipart and also change the method to POST:
<form method="POST" action="uploader.php" enctype="multipart/form-data">
<input type="file" name="myfile">
<input type="text" name="id">
<input type="submit" value="Upload">
</form>
in PHP page you can get the file data using $_FILES:
// I dont know what is id here? shouldn't be the auto Primary key?
$id=$_POST['id'];
//Get name of file
$imageName=$_FILES["myfile"]["name"];
//Get the binary data of the image
$imageData= addslashes(file_get_contents($_FILES['myfile']['temp_name']));
$connection = mysqli_connect ($db_host,$db_user,$db_pass);
mysqli_select_db($connection,$db_name);
$sql1 = "INSERT INTO figures (Id, Name, ImageData) VALUES ('$id', '$imageName', '$imageData')";
mysqli_query($connection,$sql1);
Please note that the type of column imageData should be BLOB.
As you have mentioned the you are new to programming, I have to say that you have this option too to uplaod the file directly to the server and only save the url in database.

How can I list app engine datastore parent values with python?

Not sure if on the title I should have said parent values or ancestors, but here is what I am trying to do.
I am learning to use Python in Google App Engine. While I am reviewing the content of this page in the Guestbook tutorial, I was wondering if I could enhance it by listing all possible guestbooks created.
To give a bit of context, this is how the sample code works. The application renders a page that allows you to create a guestbook entry, as well as switching/creating new guestbooks for current or future entries. I thought it would be simple to add the ability to list all currently stored guestbooks to dynamically generate a list of links to see each one.
I thought this was very simple, but I am trying and I can't figure it out. How do I query the datastore to give me a list of all the "guestbooks" available so I can build the links dynamically? If the guestbook is called guestbook_2 the url looks like this "?guestbook_name=guestbook_2".
Here is the code of the application (I added the string "INSERT LIST HERE" where I want to addd the list of links I just mentioned):
import cgi
import urllib
from google.appengine.api import users
from google.appengine.ext import ndb
import webapp2
MAIN_PAGE_FOOTER_TEMPLATE = """\
<form action="/sign?%s" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
<hr>
<form>Guestbook name (you can create your own guestbook here):
<input value="%s" name="guestbook_name">
<input type="submit" value="switch">
</form>
%s
<br><br>
List of guestbooks: %s
</body>
</html>
"""
DEFAULT_GUESTBOOK_NAME = 'default_guestbook'
# We set a parent key on the 'Greetings' to ensure that they are all in the same
# entity group. Queries across the single entity group will be consistent.
# However, the write rate should be limited to ~1/second.
def guestbook_key(guestbook_name=DEFAULT_GUESTBOOK_NAME):
"""Constructs a Datastore key for a Guestbook entity with guestbook_name."""
return ndb.Key('Guestbook', guestbook_name)
class Greeting(ndb.Model):
"""Models an individual Guestbook entry with author, content, and date."""
author = ndb.UserProperty()
content = ndb.StringProperty(indexed=False)
date = ndb.DateTimeProperty(auto_now_add=True)
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.write('<html><body>')
guestbook_name = self.request.get('guestbook_name',
DEFAULT_GUESTBOOK_NAME)
# Ancestor Queries, as shown here, are strongly consistent with the High
# Replication Datastore. Queries that span entity groups are eventually
# consistent. If we omitted the ancestor from this query there would be
# a slight chance that Greeting that had just been written would not
# show up in a query.
greetings_query = Greeting.query(
ancestor=guestbook_key(guestbook_name)).order(-Greeting.date)
greetings = greetings_query.fetch(10)
for greeting in greetings:
if greeting.author:
self.response.write(
'<b>%s</b> wrote:' % greeting.author.nickname())
else:
self.response.write('An anonymous person wrote:')
self.response.write('<blockquote>%s</blockquote>' %
cgi.escape(greeting.content))
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
# Write the submission form and the footer of the page
sign_query_params = urllib.urlencode({'guestbook_name': guestbook_name})
self.response.write(MAIN_PAGE_FOOTER_TEMPLATE %
(sign_query_params,
cgi.escape(guestbook_name),
url,
url_linktext,
"INSERT LIST HERE"
))
class Guestbook(webapp2.RequestHandler):
def post(self):
# We set the same parent key on the 'Greeting' to ensure each Greeting
# is in the same entity group. Queries across the single entity group
# will be consistent. However, the write rate to a single entity group
# should be limited to ~1/second.
guestbook_name = self.request.get('guestbook_name',
DEFAULT_GUESTBOOK_NAME)
greeting = Greeting(parent=guestbook_key(guestbook_name))
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
query_params = {'guestbook_name': guestbook_name}
self.redirect('/?' + urllib.urlencode(query_params))
application = webapp2.WSGIApplication([
('/', MainPage),
('/sign', Guestbook),
], debug=True)
Just store the guestbook name somewhere, or the easiest thing is you can fetch all the Greeting's key to get the parent, something like
guestbooks = [greeting.key().parent().name() for greeting in Greeting.all(keys_only=True)]

Google App Engine + Validation

I am looking for how to do validation on Google App Engine and I have found only how to do it using Django framework. Ok Django approach is ok but if I have one form and this form have data from few tables what then???
I can not do it like this:
class Item(db.Model):
name = db.StringProperty()
quantity = db.IntegerProperty(default=1)
target_price = db.FloatProperty()
priority = db.StringProperty(default='Medium',choices=[
'High', 'Medium', 'Low'])
entry_time = db.DateTimeProperty(auto_now_add=True)
added_by = db.UserProperty()
class ItemForm(djangoforms.ModelForm):
class Meta:
model = Item
exclude = ['added_by']
class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write('<html><body>'
'<form method="POST" '
'action="/">'
'<table>')
# This generates our shopping list form and writes it in the response
self.response.out.write(ItemForm())
self.response.out.write('</table>'
'<input type="submit">'
'</form></body></html>')
def post(self):
data = ItemForm(data=self.request.POST)
if data.is_valid():
# Save the data, and redirect to the view page
entity = data.save(commit=False)
entity.added_by = users.get_current_user()
entity.put()
self.redirect('/items.html')
else:
# Reprint the form
self.response.out.write('<html><body>'
'<form method="POST" '
'action="/">'
'<table>')
self.response.out.write(data)
self.response.out.write('</table>'
'<input type="submit">'
'</form></body></html>')
Is any easy way to validate form which contain data from few tables or I have to code it alone?
Looks like you're using webapp; I suggest your look at some other 'light-weight' choices for form validation. Pick one that you like the layout / syntax of. You'll be able to define complex 'nested' relationships if needed.
FormEncode
Formish
Deform
WTForms has a GAE component WTForms
WTForms now includes support for AppEngine fields as well as auto-form generation. The form class can be used as it is or serve as a base for extended form classes, which can then mix non-model related fields, subforms with other model forms, among other possibilities.

Resources