Understanding and implementing routes and db access in Pyramid - python

I am trying to figure out the best method of accessing all the matching microseries found in the Assessment class (table) in my database. I am trying to create a link that will send a user to those matching microseries. I am new and want to better understand the nuts and bolts of front-end engineering. I also have not seen a similar question asked here on Stacks.
I am not using JSON or XML yet, so this is a static HTML process. I have a few routes that access assessments at the moment, e.g.:
config.add_route('assessments', '/assessments')
config.add_route('assessment', '/assessments/{id:\d+}')
What I would like to better understand while implementing a method of finding matching microseries in the Assessment table and sending the user to a new page with those matching series:
How routes work, especially when accessing an attribute of a class, e.g. Assessment.microseries.
The goal of View code to convey the method mentioned above.
Pyramid links and Pyramid on Routes and URL Dispatch
Using: Python 2.7, SQLAlchemy, Pyramid
Assessment table:
class Assessment(Base):
__tablename__ = 'assessments'
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
text = Column(String(2000))
microseries = Column(Integer)
# more code
def __init__(self, name, text, user, video, categories, microseries):
# more code
API for interacting with an assessment is based on CRUD- create, retrieve, update and delete.
View Code:
this is not doing what I need it to do as I don't have a form of link to send the user to the matching series, e.g. Link1 would send a user to a new view with GET for all subseries of Link1: 1a, 1b, 1c....
#view_config(route_name='assessments', request_method='GET', renderer='templates/unique_assessments.jinja2', permission='create')
def view_unique_microseries_group(request):
logged_in_userid = authenticated_userid(request)
if logged_in_userid is None:
raise HTTPForbidden()
all_assessments = api.retrieve_assessments() #all assessments in a list
assessments_by_microseries = {} #dictonary
for x in all_assessments:
if x.microseries in assessments_by_microseries:
print("Already seen this microseries: %s" % x.microseries)
else:
assessments_by_microseries[x.microseries] = x
unique_assessments = sorted(assessments_by_microseries.values()) #.values() method to get the, err, values of the dict.
print 'unique_assessments:', unique_assessments
#a = HTTPSeeOther(location=request.route_url('view_microseries'))
return {'logged_in': logged_in_userid, 'unique_assessments': unique_assessments} #need to send some kind of list that can be shown on the template to send a user to the appropriately matching set of microseries

Related

Django Save Multiple Objects At Once

I have been practicing Django for a while now. Currently I am using it in a project where I'm fetching Facebook data via GET requests and then saving it to an sqlite database using Django models. I would like to know how can I improve the following code and save a list of Facebook posts and their metrics efficiently. In my current situation, I am using a for loop to iterate on a list containing several Facebook Posts and their respective metrics which is then associated to the specific Django model and finally saved.
def save_post(post_id, page_id):
facebook_post = Post(post_id=post_id,
access_token=fb_access_token)
post_db = PostsModel(page_id=page_id, post_id=post.post_id)
post_db.message = facebook_post.message
post_db.story = facebook_post.story
post_db.full_picture = facebook_post.full_picture
post_db.reactions_count = facebook_post.reactions_count
post_db.comments_count = facebook_post.comments_count
post_db.shares_count = facebook_post.shares_count
post_db.interactions_count = facebook_post.interactions_count
post_db.created_time = facebook_post.created_time
post_db.published = facebook_post.published
post_db.attachment_title = facebook_post.attachment_title
post_db.attachment_description = facebook_post.attachment_description
post_db.attachment_target_url = facebook_post.attachment_target_url
post_db.save()
post_db is a Django model object instantiated using PostsModel while Post is a normal Python Class which I wrote. The latter is simply a collection of GET requests which fetches data from Facebook's Graph API and returns JSON data whereby I associate relevant data to class attributes (message, 'shares_count`).
I read about the bulk_create function from Django's documentation but I don't know how to pass on the above. I also tried using multiprocessing and Pool but the above function does execute. Right now, I am just iterating sequentially on a list. As the list increases in length, it takes more time to save.
def create(self, request):
page_id = request.data['page_id']
page = get_object_or_404(PagesModel, pk=page_id)
post_list = get_list_or_404(PostsModel, page_id=page_id)
for post_id in post_list:
save_post(post_id=post_id, page_id=page)
The above function gets an already saved list from the database for a specific page based on the page_id. Then, the for loop iterates on each post in the list and its post_id and page instance are sent to the save_post function to fetch its data and save it.
Huge thanks if anyone can suggest a more effective way to tackle this. Thank you.
You are going in the right direction with the bulk_load. Generate a list of the PostsModel objects and then use bulk_create to upload them into the database. An important note here is that it won't work if the posts already exist in the database. For updating posts, try the bulk_update.
def save_post(post_id, page_id):
facebook_post = Post(post_id=post_id,
access_token=fb_access_token)
post_db = PostsModel(page_id=page_id, post_id=post.post_id)
post_db.message = facebook_post.message
post_db.story = facebook_post.story
post_db.full_picture = facebook_post.full_picture
post_db.reactions_count = facebook_post.reactions_count
post_db.comments_count = facebook_post.comments_count
post_db.shares_count = facebook_post.shares_count
post_db.interactions_count = facebook_post.interactions_count
post_db.created_time = facebook_post.created_time
post_db.published = facebook_post.published
post_db.attachment_title = facebook_post.attachment_title
post_db.attachment_description = facebook_post.attachment_description
post_db.attachment_target_url = facebook_post.attachment_target_url
return post_db
def create(self, request):
page_id = request.data['page_id']
page = get_object_or_404(PagesModel, pk=page_id)
post_list = get_list_or_404(PostsModel, page_id=page_id)
post_model_list = [save_post(post_id=post_id, page_id=page) for post_id in
post_list]
PostsModel.objects.bulk_create(post_model_list]

Store incoming sms number in server(TypeError: 'type' object is not iterable)

Newbie to python and django. I have a ideal to develop a sms marketing campaign. I'm using Twilio Api, Django framework, django_twilio. I will be sending out mass text messages introducing my business and will allow subscriptions to different types of offers based on keyword responses. I've been able to send out the messages and pull the number from the respondents. I'm puzzled about how would I code taking those numbers and store them in the database in a way that would have those who want to subscribe to one offer in a viewable listing and those who want to subscribe to other offers in their own viewable list. I have little experience, but so far this is what Ive manage to get on my own. By "viewable list" I intend to keep count of how subscribers I have for each offer so that i can present to my clients as to say "I Have this {} many subscribers to your offer"
views.py
from django.http import request
from django_twilio.decorators import twilio_view
from django_twilio.request import decompose
from twilio.twiml.messaging_response import MessagingResponse
from .models import OfferListing
#twilio_view
def sms_choice(request):
twilio_request = decompose(request)
contact_num = twilio_request.from_
response = twilio_request.body
resp = MessagingResponse()
if response == 'Doctor':
OfferListing(doctor_list=contact_num)
resp.message('Thanks for subscribing')
elif response == 'Dentist':
OfferListing(dentist_list=contact_num)
resp.message('Thanks for subscribing')
print(contact_num, response)
return str(resp)
models.py
from django.db import models
#Available Listing
class OfferListing (models.Model):
doctor_list = [models.BigAutoField()]
dentist_list = [models.BigAutoField()]
def __unicode__(self):
return self
#Customer Numbers
class Contacts (models.Model):
number = models.BigAutoField(primary_key=True)
def __unicode__(self):
return self
#Based on response add contact to Offerlistings
class Subscription (models.Model):
number = models.ForeignKey('OfferListing',
on_delete=models.CASCADE,
related_name='number_sub')
choice = models.ManyToManyField(OfferListing)
def __unicode__(self):
return self
I would recommend 3 models: a table with the phone number you texted and any info about that person you have, a table with the available 'lists' you offer, and a 3rd table that foreign keys to both of those tables. This can change depending on if a person can belong to multiple lists. In that case, you would need a manytomany model.
You don't want to have a different model for each list. Imagine your business takes off and you have to maintain 500 different lists (doctor, dentist, vet, OBGYN, ENT, Cardio, neuro, etc). You don't want to maintain all that. Instead, have a model that contains all your lists and then have a model that ties a phone number to the list they have subscribed to. That way, each time you add a new list, it is one entry in a table instead of a whole new class in your models module.
To retrieve your list of people subscribed, you can use the Django db API to return all the people like:
ListsTable.objects.filter(listid = 1)
And that would return all the phone numbers that are subscribed.

GAE webapp2 delete all UserTokens (drop all sessios) for specific user

I want to drop all user sessions when user resets his password, but I can't find a way to do that.
My idea was to get all UserTokens of the specific user and delete them, but it seems impossible, because of
user = model.StringProperty(required=True, indexed=False)
in UserToken model
Any ideas how to do that?
I see two ways how to do that.
First is to inherit from the UserToken class making user an indexed property. Then you can set the token_model class property to your new token model in your user class. Here is the code:
class MyToken(UserToken):
user = ndb.StringProperty(required=True)
class MyUser(User):
token_model = MyToken
# etc.
Don't forget to set the user model used by webapp2 to your user class if you do not do it already:
webapp2_config = {
"webapp2_extras.auth": {
"user_model": "models.MyUser"
},
# etc.
}
app = webapp2.WSGIApplication(routes, config=webapp2_config)
The second way is to make a complicated datastore query based on the token key name. Since the key names are of the form <user_id>.<scope>.<random>, it is possible to retrieve all the entities starting with a specific user ID. Have a look at the code:
def query_tokens_by_user(user_id):
min_key = ndb.Key(UserToken, "%s." % user_id)
max_key = ndb.Key(UserToken, "%s/" % user_id) # / is the next ASCII character after .
return UserToken.query(UserToken.key > min_key, UserToken.key < max_key)
This uses the fact that the query by key names works in the lexicographical order.

Python model of Google Contact for appengine datastore

I would like to save contacts on AppEngine datastore from the Google API v3. I want to know what is the best way to store these data and especially if there is already a model!
Looking at the sources of gdata, I found a very interesting beginning. But this is the modeling of the data only in python and not for the datastore.
Question : Is this model already exists in python?
If not:
Question : What is the best way to start from scratch?
Beginning example of a contact in Python :
class Contact(db.Model):
"""
https://developers.google.com/gdata/docs/2.0/elements?hl=fr#gdContactKind
https://developers.google.com/appengine/docs/python/datastore/datamodeling
"""
content = db.Text()
"""atom:content Notes about the contact."""
link = db.ListProperty(Link,indexed=False,default=[])
"""atom:link* Links to related information. Specifically, atom:link[#rel='alternate'] links to an HTML page describing the contact."""
title = db.StringProperty()
"""atom:title Contact's name. This field is read only. To modify the contact's name, see gd:name."""
email = db.ListProperty(Email,indexed=False,default=[])
"""gd:email* Email addresses."""
"""etc..."""
class Link(db.Model):
"""
Link
"""
link = db.LinkProperty()
class Email(db.Model):
"""
Email
"""
email_address = db.EmailProperty()
class EmailImParent(db.Model):
address = db.StringProperty()
label = db.StringProperty()
rel = db.StringProperty()
primary = db.StringProperty()
class Email(db.Model,EmailImParent):
"""
The gd:email element.
"""
email = db.EmailProperty()
display_name = db.StringProperty()
I think everyone is rolling their own. It is easy enough to do, you can take a look at AE-BaseApp/Python and check out the code from the Github link. I have some new code that will be updated in the near future that contains some improvements to the contact model. (the updated code is currently broken due to hacking to get logins working on both http and https here)

How to query datastore when using ReferenceProperty?

I am trying to understand the 1-to-many relationships in datastore; but I fail to understand how query and update the record of a user when the model includes ReferenceProperty. Say I have this model:
class User(db.Model):
userEmail = db.StringProperty()
userScore = db.IntegerProperty(default=0)
class Comment(db.Model):
user = db.ReferenceProperty(User, collection_name="comments")
comment = db.StringProperty()
class Venue(db.Model):
user = db.ReferenceProperty(User, collection_name="venues")
venue = db.StringProperty()
If I understand correctly, the same user, uniquely identified by userEmail can have many comments and may be associated with many venues (restaurants etc.)
Now, let's say the user az#example.com is already in the database and he submits a new entry.
Based on this answer I do something like:
q = User.all()
q.filter("userEmail =", az#example.com)
results = q.fetch(1)
newEntry = results[0]
But I am not clear what this does! What I want to do is to update comment and venue fields which are under class Comment and class Venue.
Can you help me understand how this works? Thanks.
The snippet you posted is doing this (see comments):
q = User.all() # prepare User table for querying
q.filter("userEmail =", "az#example.com") # apply filter, email lookup
- this is a simple where clause
results = q.fetch(1) # execute the query, apply limit 1
the_user = results[0] # the results is a list of objects, grab the first one
After this code the_user will be an object that corresponds to the user record with email "az#example.com". Seing you've set up your reference properties, you can access its comments and venues with the_user.comments and the_user.venues. Some venue of these can be modified, say like this:
some_venue = the_user.venues[0] # the first from the list
some_venue.venue = 'At DC. square'
db.put(some_venue) # the entry will be updated
I suggest that you make a general sweep of the gae documentation that has very good examples, you will find it very helpful:
http://code.google.com/appengine/docs/python/overview.html
** UPDATE **: For adding new venue to user, simply create new venue and assign the queried user object as the venue's user attribute:
new_venue = Venue(venue='Jeferson memorial', user=the_user) # careful with the quoting
db.put(new_venue)
To get all Comments for a given user, filter the user property using the key of the user:
comments = Comment.all().filter("user =", user.key()).fetch(50)
So you could first lookup the user by the email, and then search comments or venues using its key.

Categories

Resources