diff --git a/hasjob/models/board.py b/hasjob/models/board.py index 609f9ce94..3a93dba87 100644 --- a/hasjob/models/board.py +++ b/hasjob/models/board.py @@ -4,7 +4,6 @@ from pytz import timezone from werkzeug import cached_property from flask import url_for, Markup -from sqlalchemy.orm import defer from sqlalchemy.ext.associationproxy import association_proxy from coaster.sqlalchemy import make_timestamp_columns from . import db, TimestampMixin, BaseNameMixin @@ -218,7 +217,7 @@ def get(cls, name): def _user_boards(self): return Board.query.filter( Board.userid.in_(self.user_organizations_owned_ids())).options( - defer(Board.description)).all() + db.load_only('id', 'name', 'title', 'userid')).all() User.boards = _user_boards diff --git a/hasjob/models/jobpost.py b/hasjob/models/jobpost.py index cb5dad20f..02e3e91ee 100644 --- a/hasjob/models/jobpost.py +++ b/hasjob/models/jobpost.py @@ -137,7 +137,7 @@ class JobPost(BaseMixin, db.Model): language = db.Column(db.CHAR(2), nullable=True) language_confidence = db.Column(db.Float, nullable=True) - admins = db.relationship(User, secondary=lambda: jobpost_admin_table, + admins = db.relationship(User, lazy='dynamic', secondary=lambda: jobpost_admin_table, backref=db.backref('admin_of', lazy='dynamic')) starred_by = db.relationship(User, lazy='dynamic', secondary=starred_job_table, backref=db.backref('starred_jobs', lazy='dynamic')) @@ -173,6 +173,14 @@ class JobPost(BaseMixin, db.Model): defer('language'), defer('language_confidence'), + # These are defined below JobApplication + defer('new_applications'), + defer('replied_applications'), + defer('viewcounts_impressions'), + defer('viewcounts_viewed'), + defer('viewcounts_opened'), + defer('viewcounts_applied'), + # defer('pay_type'), # defer('pay_currency'), # defer('pay_cash_min'), @@ -191,7 +199,7 @@ def __repr__(self): def admin_is(self, user): if user is None: return False - return user == self.user or user in self.admins + return user == self.user or bool(self.admins.options(db.load_only('id')).filter_by(id=user.id).count()) @property def expiry_date(self): @@ -415,27 +423,31 @@ def viewcounts(self): values = redis_store.hgetall(cache_key) if 'impressions' not in values: # Also see views.helper.save_impressions for a copy of this query - values['impressions'] = db.session.query(db.func.count( - db.func.distinct(EventSession.user_id)).label('count')).join( - JobImpression).filter(JobImpression.jobpost == self).first().count + # values['impressions'] = db.session.query(db.func.count( + # db.func.distinct(EventSession.user_id)).label('count')).join( + # JobImpression).filter(JobImpression.jobpost == self).first().count + values['impressions'] = self.viewcounts_impressions redis_store.hset(cache_key, 'impressions', values['impressions']) redis_store.expire(cache_key, 86400) else: values['impressions'] = int(values['impressions']) if 'viewed' not in values: - values['viewed'] = UserJobView.query.filter_by(jobpost=self).count() + # values['viewed'] = UserJobView.query.filter_by(jobpost=self).count() + values['viewed'] = self.viewcounts_viewed redis_store.hset(cache_key, 'viewed', values['viewed']) redis_store.expire(cache_key, 86400) else: values['viewed'] = int(values['viewed']) if 'opened' not in values: - values['opened'] = UserJobView.query.filter_by(jobpost=self, applied=True).count() + # values['opened'] = UserJobView.query.filter_by(jobpost=self, applied=True).count() + values['opened'] = self.viewcounts_opened redis_store.hset(cache_key, 'opened', values['opened']) redis_store.expire(cache_key, 86400) else: values['opened'] = int(values['opened']) if 'applied' not in values: - values['applied'] = JobApplication.query.filter_by(jobpost=self).count() + # values['applied'] = JobApplication.query.filter_by(jobpost=self).count() + values['applied'] = self.viewcounts_applied redis_store.hset(cache_key, 'applied', values['applied']) redis_store.expire(cache_key, 86400) else: @@ -526,14 +538,6 @@ def viewstats(self): else: return 'd', viewstats_by_id_day(self.id) - @property - def new_applications(self): - return JobApplication.query.filter_by(jobpost=self, response=EMPLOYER_RESPONSE.NEW).count() - - @property - def replied_applications(self): - return JobApplication.query.filter_by(jobpost=self, response=EMPLOYER_RESPONSE.REPLIED).count() - def reports(self): if not self.flags: return [] @@ -876,6 +880,36 @@ def url_for(self, action='view', _external=False, **kwargs): db.desc(JobApplication.created_at)), cascade='all, delete-orphan')) +JobPost.new_applications = db.column_property( + db.select([db.func.count(JobApplication.id)]).where( + db.and_(JobApplication.jobpost_id == JobPost.id, JobApplication.response == EMPLOYER_RESPONSE.NEW))) + + +JobPost.replied_applications = db.column_property( + db.select([db.func.count(JobApplication.id)]).where( + db.and_(JobApplication.jobpost_id == JobPost.id, JobApplication.response == EMPLOYER_RESPONSE.REPLIED))) + + +JobPost.viewcounts_impressions = db.column_property( + db.select([db.func.count(db.func.distinct(EventSession.user_id))]).where( + db.and_(JobImpression.event_session_id == EventSession.id, JobImpression.jobpost_id == JobPost.id))) + + +JobPost.viewcounts_viewed = db.column_property( + db.select([db.func.count()]).where( + UserJobView.jobpost_id == JobPost.id)) + + +JobPost.viewcounts_opened = db.column_property( + db.select([db.func.count()]).where( + db.and_(UserJobView.jobpost_id == JobPost.id, UserJobView.applied == True))) # NOQA + + +JobPost.viewcounts_applied = db.column_property( + db.select([db.func.count(JobApplication.id)]).where( + JobApplication.jobpost_id == JobPost.id)) + + def unique_hash(model=JobPost): """ Returns a unique hash for a given model diff --git a/hasjob/views/listing.py b/hasjob/views/listing.py index 5b346826f..c4d3cfb8d 100644 --- a/hasjob/views/listing.py +++ b/hasjob/views/listing.py @@ -53,8 +53,7 @@ def jobdetail(domain, hashid): is_siteadmin = lastuser.has_permission('siteadmin') query = JobPost.query.filter_by(hashid=hashid).options( - db.subqueryload('locations'), db.subqueryload('taglinks') - ) + db.subqueryload('locations'), db.subqueryload('taglinks')) # if g.user: # query = query.outerjoin(UserJobView, # db.and_(UserJobView.user_id == g.user.id, UserJobView.jobpost_id == JobPost.id))