I'm creating my very first web app with Flask. It must connect to MySQL (table called "Tasks") with SQLAlchemy and after that output all tasks from this table. All "tasks" have fields "StartDevelop" and "FinishDevelop" (DateTime fields). So my task is to output two buttons next to every name of "task". They must work with MySQL and send current time.
How can I connect two buttons to every row and connect all of them to python's script?
Example:
task1(string), AcceptTask1(button), CompleteTask1(button)
task2(string), AcceptTask2(button), CompleteTask2(button)
task3(string), AcceptTask3(button), CompleteTask3(button)
task4(string), AcceptTask4(button), CompleteTask4(button)
...
where number of tasks is accepted from datebase.
Code I made
I made dictionary, where key is task.Id and value is form(with string fields and two buttons). I also using field.descriptions to output/not output them.
#app.route('/database', methods=['GET','POST'])
#login_required
def database():
page = request.args.get('page', 1, type=int)
tasks = Tasks.query.filter(current_user.Id == Tasks.Developer or current_user.Id == Tasks.Reviewer).paginate(page, app.config['TASKS_PER_PAGE'], False)
forms = dict()
for task in tasks.items:
forms[task.Id] = DataBaseForm()
forms[task.Id].set_values(task,current_user)
class DataBaseForm(FlaskForm):
eord = StringField()
task = StringField()
assign_date = DateTimeField()
type = StringField()
accept_date = DateTimeField()
accepted = SubmitField(label = 'Submit', description = 'Submit')
comment = StringField()
completed = SubmitField(label = 'Submit', description = None)
def set_values(self, task, user):
self.eord.description = task.course.Name
self.task.description = task.Name
self.assign_date.description = task.Created
if (user.Id == task.Developer):
if(task.EndDevelop):
self.accept_date.description = task.EndDevelop
self.accepted.description = ""
else:
self.accepted.description = 'Submit'
self.comment.description = 'Comment'
if (user.Id == task.Reviewer):
if(task.EndReview):
self.accept_date.description = task.EndReview
self.accepted.description = ""
else:
self.accepted.description = 'Submit'
self.comment.description = 'Comment'
if(task.EndReview and task.EndDevelop):
self.completed.description = 'Complete'
Related
So I am extremely new to programming, and am stuck at this issue, I am using python with Django and Mongodb for database. I need to write a service that assigns an ID (not the one assigned by mongodb) upon each user form submission. for example entry 1's ID will be [Prefix entered by user] 2101, entry 2's ID will be [Prefix entered by user] 2102, so its basically adding in the number 2100.
I have no idea how and where to integrate this logic in my code. I have tried a few solutions on the internet but nothing seems to work.
my code:
Model.py
class Writeups(Document):
blog_id = 2100
title = fields.StringField(max_length=120)
date_created = fields.DateField(blank=True, null=True)
date_modified = fields.DateField(blank=True, null=True)
version_number = fields.DecimalField(null= True , max_digits=1000, decimal_places=2)
storage_path = fields.StringField(max_length=120)
STRIKE_READY_BRIEF = 'SRB'
STRIKE_READY_THREAT_REPORT = 'SRTR'
PREFIX_CHOICES = [
(STRIKE_READY_BRIEF, 'SRB'),
(STRIKE_READY_THREAT_REPORT, 'SRTR'),
]
prefix = fields.StringField(
max_length=4,
choices=PREFIX_CHOICES,
null=False,
blank=False,
)
views.py:
#csrf_exempt
def writeups_request(request):
"""
Writeup Request
"""
if request.method == 'GET':
try:
data = {
'form-TOTAL_FORMS': '1',
'form-INITIAL_FORMS': '0',
}
writeups = WriteupsFormset(data)
# print(writeup)
return render(request, "writeups/writeups.html", {'writeups_forms': writeups})
except Exception as e:
print(e)
response = {"error": "Error occurred"}
return JsonResponse(response, safe=False)
if request.method == 'POST':
writeup_data = WriteupsFormset(request.POST)
if writeup_data.is_valid():
flag = False
logs = []
for writeups_data in writeup_data:
print(writeups_data)
if writeups_data.cleaned_data.get('DELETE'): # and malware_data._should_delete_form(form):
continue
title = writeups_data.cleaned_data.get('title')
date_created = writeups_data.cleaned_data.get('date_created')
date_modified = writeups_data.cleaned_data.get('date_modified')
version_number = writeups_data.cleaned_data.get('version_number')
storage_path = writeups_data.cleaned_data.get('storage_path')
prefix = writeups_data.cleaned_data.get('prefix')
try:
writeups = Writeups(),
title=title,
date_created=date_created,
date_modified=date_modified,
version_number=version_number,
storage_path=storage_path,
prefix=prefix)
writeups.save()
In order to implement your custom script at all submissions, Django's Signals are the solution for your use case. Look into post_save and pre-save signals and use them as per your problem.
https://docs.djangoproject.com/en/3.2/ref/signals/
If you have an existing database and you want a script to iterate through it and update the dataset, you can take a look at Management Commands
https://docs.djangoproject.com/en/4.0/howto/custom-management-commands/
I am pulling data from a json file on the web, and updating it in my django database. I want to keep track of users that are associated with each team, but as soon as a user loads the page once they are added to the model. How do I avoid this?
class Team(models.Model):
name = models.CharField(max_length=120)
abbreviation = models.CharField(max_length=3)
id = models.IntegerField(primary_key=True)
link = models.CharField(max_length=120)
wins = models.IntegerField(default=0)
losses = models.IntegerField(default=0)
ties = models.IntegerField(default=0)
points = models.IntegerField(default=0)
users = models.ManyToManyField(User)
def getTeams():
import requests
baseUrl = "https://statsapi.web.nhl.com/"
# INITALIZING THE DATA IN THE DATA DICTIONARY
r = requests.get(baseUrl + '/api/v1/teams')
originalData = r.json()
# i dont need the copyright, only care about the teams
originalData = originalData["teams"]
for team in originalData:
id = team["id"]
try:
databaseTeam = Team.objects.get(id = id)
except Exception:
Team.objects.create(id = id)
databaseTeam = Team.objects.get(id = id)
databaseTeam.name = team["name"]
databaseTeam.abbreviation = team["abbreviation"]
databaseTeam.link = team["link"]
databaseTeam.save()
print("done")
#login_required
def myTeamView(request):
t1 = Thread(target=getTeams)
t1.start()
return(render(request, "teams/myTeams.html", {}))
The user is stored on user variable inside the request, so first we need to pass it to getTeams method. Then we use the method add of Manytomany fields to append an record to it, in this case the user.
def getTeams(request):
import requests
baseUrl = "https://statsapi.web.nhl.com/"
# INITALIZING THE DATA IN THE DATA DICTIONARY
r = requests.get(baseUrl + '/api/v1/teams')
originalData = r.json()
# i dont need the copyright, only care about the teams
originalData = originalData["teams"]
for team in originalData:
id = team["id"]
try:
databaseTeam = Team.objects.get(id = id)
except Exception:
Team.objects.create(id = id)
databaseTeam = Team.objects.get(id = id)
databaseTeam.name = team["name"]
databaseTeam.abbreviation = team["abbreviation"]
databaseTeam.link = team["link"]
databaseTeam.save()
databaseTeam.users.add(request.user) # after save!!
print("done")
#login_required
def myTeamView(request):
t1 = Thread(target=getTeams, args=(request, ))
t1.start()
return(render(request, "teams/myTeams.html", {}))
So I am trying to create a unique permalink each time that a person posts on my webpage and I want it to be relatively search engine friendly so I have made a little code to change the title to a good search engine title and it is working but then my handler cannot accept it. At least that is what I think is happening because the webpage just gives me a 404 error. The HTML works fine because when I redirect to a static page it all goes through. Here is the applicable code:
def post(self):
subject = self.request.get('subject')
content = self.request.get('content')
if subject and content:
p = Post(parent = blog_key(), subject = subject, content = content)
p.put()
id=str(p.key().id())
subject = str(subject)
subject = subject.replace(' ', '25fdsa67ggggsd5')
subject = ''.join(e for e in subject if e.isalnum())
subject = subject.replace('25fdsa67ggggsd5', '-')
subject = subject.lower()
url = '/blog/%s/%s' % (id, subject)
self.redirect('/blog/%s/%s' % (id, subject))
class PostPage(BlogHandler):
def get(self, post_id):
key = db.Key.from_path('PersonalPost', int(post_id), parent=blog_key())
post = db.get(key)
if not post:
self.error(404)
return
self.render("permalink.html", post = post)
class PersonalPost(db.Model):
subject = db.StringProperty(required = True)
content = db.TextProperty(required = True)
created = db.DateTimeProperty(auto_now_add = True)
last_modified = db.DateTimeProperty(auto_now = True)
user_id = db.StringProperty(required = True)
def render(self):
self._render_text = self.content.replace('\n', '<br>')
return render_str("post.html", p = self)
def blog_key(name = 'default'):
return db.Key.from_path('blogs', name)
app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
And again it works when I just have it redirect to the main page and list them but not when I try to direct to the new SEO page.
UPDATE:
The test url I am using is setting
subject = "test-url"
id = "1234"
The app then directs me to www.url.com/blog/1234/test-url but it gives me a 404 error.
You define two groups in ('/blog/([0-9]+)/([.*]+) but your PostPage.get() only takes one.
Change it to def get(self, post_id, subject) or remove the second group ('/blog/([0-9]+)/[.*]+
I think you should have a look at the quotes on ur handler mapping, it seems inconsistent.
yours: app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
try : app = webapp2.WSGIApplication(['/blog/([0-9]+)/([.*]+)', PostPage)]
Im trying to make 3 database; person, event and hobby. Each person selects hobbies from the list that is provided, which are in the hobby database. when a person creates a event, that person choose which hobby will be tagged to that event. From there event invitation will be send out to person who selected that hobby. And the event will be made using Google Calendar API....
im stuck on making this 3 database and trying to relate them using either relationalproperty or list property... looked around but not too good with programming so im kinda stuck...
if anyone could help me that would be really appreciated.
class Hobby(db.Model):
name = db.StringProperty()
#property
def members(self):
return Person.all().filter('hobby', self.key())
h1 = Hobby(key_name ='key1', name = 'tennis')
h2 = Hobby(name = 'basketball')
h1.put()
h2.put()
class Person(db.Model):
name = db.StringProperty()
hobby = db.ListProperty(db.Key)
p1 = Person(name = 'tom', hobby = Hobby.get_by_key_name(['key1']))
p1.put()
class Event(db.Model):
title = db.StringProperty(required=True)
description = db.TextProperty()
time = db.DateTimeProperty()
location = db.TextProperty()
creator = db.UserProperty()
edit_link = db.TextProperty()
gcal_event_link = db.TextProperty()
gcal_event_xml = db.TextProperty()
hobby = db.ListProperty(db.Key)
#property
def members(self):
return Person.all().filter('event', self.key())
class Attendee(db.Model):
email = db.StringProperty()
event = db.ReferenceProperty(Event)
hobby = db.ReferenceProperty(Hobby)
class Greeting(db.Model):
author = db.UserProperty()
content = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
class BasePage(webapp.RequestHandler):
title = ''
def write_page_header(self):
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('<html><head><title>%s</title>'
'<link href="static/invitations.css" rel="stylesheet" type="text/css"/>'
'</head><body><div id="main">' % (
self.title,))
self.write_signin_links()
def write_signin_links(self):
if users.get_current_user():
template_values = {
'signed_in': True,
'user_link': users.create_logout_url('/')}
else:
template_values = {
'signed_in': False,
'user_link': users.create_login_url('/events')}
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'signin.html')
self.response.out.write(template.render(path, template_values))
def write_page_footer(self):
self.response.out.write('</div></body></html>')
class StartPage(BasePage):
title = 'One Macnica'
def get(self):
self.write_page_header()
template_values = {'sign_in': users.create_login_url('/events')}
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'start.html')
self.response.out.write(template.render(path, template_values))
self.write_page_footer()
class EventsPage(BasePage):
title = 'One Macnica'
def __init__(self):
# Create a Google Calendar client to talk to the Google Calendar service.
self.calendar_client = gdata.calendar.service.CalendarService()
# Modify the client to search for auth tokens in the datastore and use
# urlfetch instead of httplib to make HTTP requests to Google Calendar.
gdata.alt.appengine.run_on_appengine(self.calendar_client)
def get(self):
"""Displays the events the user has created or is invited to."""
self.write_page_header()
# Find all events which this user has created, and find events which this
# user has been invited to.
invited_events = []
owned_events = []
token_request_url = None
# Find an AuthSub token in the current URL if we arrived at this page from
# an AuthSub redirect.
auth_token = gdata.auth.extract_auth_sub_token_from_url(self.request.uri)
if auth_token:
self.calendar_client.SetAuthSubToken(
self.calendar_client.upgrade_to_session_token(auth_token))
# Check to see if the app has permission to write to the user's
# Google Calendar.
if not isinstance(self.calendar_client.token_store.find_token(
'http://www.google.com/calendar/feeds/'),
gdata.auth.AuthSubToken):
token_request_url = gdata.auth.generate_auth_sub_url(self.request.uri,
('http://www.google.com/calendar/feeds/',))
query_time = self.request.get('start_time')
# TODO handle times provided in the URL.
if not query_time:
query_time = datetime.datetime.now()
# Find the events which were created by this user, and those which the user
# is invited to.
if users.get_current_user():
owned_query = Event.gql('WHERE creator = :1 ORDER BY time',
users.get_current_user())
owned_events = owned_query.fetch(5)
invited_query = Attendee.gql('WHERE email = :1',
users.get_current_user().email())
for invitation in invited_query.fetch(5):
try:
invited_events.append(invitation.event)
except db.Error, message:
if message[0] == 'ReferenceProperty failed to be resolved':
# The invitee has an invitation to an event which no longer exists.
pass
else:
raise
template_values = {
'token_request_url': token_request_url,
'owned_events': owned_events,
'invited_events': invited_events,
}
# Display the events.
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'events.html')
self.response.out.write(template.render(path, template_values))
self.write_page_footer()
def post(self):
"""Adds an event to Google Calendar."""
event_id = self.request.get('event_id')
# Fetch the event from the datastore and make sure that the current user
# is an owner since only event owners are allowed to create a calendar
# event.
event = Event.get_by_id(long(event_id))
if users.get_current_user() == event.creator:
# Create a new Google Calendar event.
event_entry = gdata.calendar.CalendarEventEntry()
event_entry.title = atom.Title(text=event.title)
event_entry.content = atom.Content(text=event.description)
if start_time is None:
start_time = '%s.000Z' % event.time.isoformat()
end_time = '%s.000Z' % event.time.isoformat(time.time()+3600)
event_entry.when.append(gdata.calendar.When(start_time=start_time, end_time=end_time))
event_entry.where.append(
gdata.calendar.Where(value_string=event.location))
# Add a who element for each attendee.
attendee_list = event.attendee_set
if attendee_list:
for attendee in attendee_list:
new_attendee = gdata.calendar.Who()
new_attendee.email = attendee.email
event_entry.who.append(new_attendee)
#Adding hobby for each attendee
"""hobby_list = event.hobby_set
if hobby_list:
for hobby in hobby_list:
new_hobby = gdata.calendar.ExtendedProperty()
new_hobby.name = hobby.name
event_entry.extended_property.append(new_hobby)
"""
# Hobby to which a person belongs:
p = db.get(person_key)
hobby = db.get(p.hobby) #batch get using list of keys
for hobby in hobby:
new_hobby = gdata.calendar.ExtendedProperty()
new_hobby = hobby.name
event_entry.extended_property.append(new_hobby)
#Person that belong to a hobby:
h = db.get(hobby_key)
for person in h.members:
new_person = gdata.calendar.Who()
new_person.name = person.name
event_entry.who.append(new_person)
# Event to which a person belongs:
p = db.get(person_key)
event = db.get(p.event)
for event in event:
new_event = gdata.calendar.ExtendedProperty()
new_event = event.title
event_entry.extended_property.append(new_event)
# Person that belong to a event:
e = db.get(event_key)
for person in e.members:
new_person = gdata.calendar.Who()
new_person.name = person.name
event_entry.who.append(new_person)
# Send the event information to Google Calendar and receive a
# Google Calendar event.
try:
cal_event = self.calendar_client.InsertEvent(event_entry,
'http://www.google.com/calendar/feeds/default/private/full')
edit_link = cal_event.GetEditLink()
if edit_link and edit_link.href:
# Add the edit link to the Calendar event to use for making changes.
event.edit_link = edit_link.href
alternate_link = cal_event.GetHtmlLink()
if alternate_link and alternate_link.href:
# Add a link to the event in the Google Calendar HTML web UI.
event.gcal_event_link = alternate_link.href
event.gcal_event_xml = str(cal_event)
event.put()
# If adding the event to Google Calendar failed due to a bad auth token,
# remove the user's auth tokens from the datastore so that they can
# request a new one.
except gdata.service.RequestError, request_exception:
request_error = request_exception[0]
if request_error['status'] == 401 or request_error['status'] == 403:
gdata.alt.appengine.save_auth_tokens({})
# If the request failure was not due to a bad auth token, reraise the
# exception for handling elsewhere.
else:
raise
else:
self.response.out.write('I\'m sorry, you don\'t have permission to add'
' this event to Google Calendar.')
# Display the list of events also as if this were a get.
self.get()
I have posted some of my code. I have edit event class and such after this but i guess its not that important in solving the database situation...
thanks in advance for any help or advice.
Your problem with creating a Person entity is that above (at p1) you're trying to assign a Hobby entity to Person.hobby which should be a list of Hobby keys (and probably be named hobbies)
h = Hobby(name='basketball')
h_key = h.put() # or after h.put(), h.key()
p = Person(name='tom', hobbies=[h_key])
p.put()
Also, your Person model has no property event so Event.members will fail.
Other than these, using db.ListProperty() is the correct way to handle many to many relationships which carry no additional information.
I'm trying to practice some django basics by implementing my own sortable table in Django and I've run into a couple of snags.
Here's the code that I'm working with in my view:
def __table_view_helper__(request):
if not request.session.__contains__('filters'):
filters = {'filterA':'',
'filterB':'',
'filterC':''}
request.session['filters'] = filters
if not request.session.__contains__('headers'):
headers = {'sortA':'asc',
'sortB':'des',
'sortC':'asc',
'sortD':'asc'}
request.session['headers'] = headers
def table_view(request):
__table_view_helper__(request)
records = Record.objects.all()
nums = list(set(records.values_list('fieldA','fieldA')))
nums.sort()
if request.method == 'POST':
filter = FilterForm(nums,request.POST)
if filter.is_valid():
fieldA = filter.cleaned_data['fieldA']
fieldB = filter.cleaned_data['fieldB']
fieldC = filter.cleaned_data['fieldC']
filters = request.session['filters']
filters['fieldA'] = fieldA
filters['fieldB'] = fieldB
filters['fieldC'] = fieldC
request.session['filters'] = filters
else:
filter = FilterForm(nums)
filters = request.session['filters']
filter.fields['fieldA'].initial = filters['fieldA']
filter.fields['fieldB'].initial = filters['fieldB']
filter.fields['fieldC'].initial = filters['fieldC']
if filters['fieldA']:
records = records.filter(fieldA=filters['fieldA'])
if filters['fieldB']:
records = records.filter(fieldB__in=filters['fieldB'])
if filters['fieldC']:
records = records.filter(fieldC=filters['fieldC'])
sort = request.GET.get('sort')
if sort is not None:
headers = request.session['headers']
if headers[sort] == "des":
records = records.order_by(sort).reverse()
headers[sort] = "asc"
else:
records = records.order_by(sort)
headers[sort] = "des"
request.session['headers'] = headers
return render_to_response("secure/table.html",{'user':request.user,'profile':request.user.get_profile(),'records':records,'fform':filter})
I changed a lot of my code to use sessions now. It works fine. Is this a good way to do this you think?
To set the initial values from the view you have to do:
filter.fields['fieldA'].initial = filters['filterA']
To keep user related data persistent through different requests you shouldn't use globals, but sessions!