How can we query and select specific id of a notification..?
Right now following problem i'm facing... You can see in else section i am sending notification that a person followed other person. Now In if selection when a person unfollow the person he followed. That notification should be removed so that when he follow again the previous notification get removes and new one get generated. I expect kind and help full ans from you guys . Thank you !:)
if follower:
profile_.follower.remove(follower.id)
actor = User.objects.get(pk=user_id)
user = User.objects.get(username=username_to_toggle)
query = Notification.objects.filter(id__in=notificacion_ids).update(deleted=True) #notificacion_ids(I don't understand how to get that.)
print(query,"hey heyh eh")
# json_follower = some_view(user)
else:
new_follower = User.objects.get(username__iexact=username_to_toggle)
profile_.follower.add(new_follower.id)
actor = User.objects.get(pk=user_id)
user = User.objects.get(username=username_to_toggle)
notify.send(actor, recipient=user, verb='follow you')
# json_follower = some_view(username_to_toggle)
is_following = True
you would then filter the notifications model using the 'actor' and the 'recipient'. Something like this:
notification_ids =Notification.objects.filter(actor_object_id=actor.id,recipient_id=user.id).values_list('id', flat=True)
Related
I'm workin on a blog page and I'm trying to filter posts by tag, the problem is that I get several pages when only 1 or 2 posts match the query (I have per_page set to 6).
I have another filter by followed posts that works correctly, therefore I guess the problem is in the query object.
This is part of my code for the view index:
if current_user.is_authenticated:
show_followed = bool(request.cookies.get('show_followed', ''))
if show_followed:
query = current_user.followed_posts
elif show_tag:
tag = Tag.query.filter_by(tag_name=show_tag).first()
query = tag.post
else:
query = Post.query
page = request.args.get('page', 1, type=int)
pagination = query.order_by(Post.timestamp.desc()).paginate(
page, per_page=current_app.config['POSTS_PER_PAGE'],
error_out=False)
posts = pagination.items
return render_template("index.html", posts=posts, pagination = pagination, show_followed=show_followed, show_tag=show_tag)
when I try to replicate the issue in the console, I check that the query for a sample tag matches 3 posts, nevertheless pagination.total (total items) returns 23! What does the pagination object take as items??
I did this to test in the flask shell:
tagname = 'pruebatag'
tag = Tag.query.filter_by(tag_name=tagname).first()
query = tag.post
#here if y try query.all() I get 3 posts in return
pag_object = query.paginate(per_page = 6)
pag_object.total
>>> 23
pag_object.pages
>>> 4
pag_object.items #returns items for current page
>>> [<Post example>] #only one post returned for this page? why 4 pages?
I copy my definition of the tags table:
class Tag(db.Model):
__tablename__ = 'tags'
id = db.Column(db.Integer, primary_key=True)
tag_name = db.Column(db.String(40), unique=True)
def add_tag(self):
if not self.id:
db.session.add(self)
db.session.commit()
tag_join = db.Table('tag_join',
db.Column('post_id', db.Integer, db.ForeignKey('post.id')),
db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'))
)
And in the post model:
tags = db.relationship('Tag',
secondary=tag_join,
backref=db.backref('post', lazy='dynamic'),
lazy='dynamic')
Any help would be highly appreciated as I am wasting a lot of time on this issue
Just let mi know if you need more details.
Thanks!
Finally I found what happens, I realize that table tag_join is full of duplicates, that cause the issue.
I'm in the process of modifying the Flask app created in following along Miguel Grinberg's Flask Mega Tutorial such that it is possible to post tweets. I have imported tweepy for accessing the twitter api and modified the databases to hold the scheduled time of a tweet.
I wish to iterate over the current_user's posts and the corresponding times from the SQLAlchemy database and post when the current time matches the scheduled time.
The database model modifications in model.py are as follows:
class Post(db.Model):
id = db.Column(db.Integer, primary_key = True)
body = db.Column(db.String(140))
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
socialnetwork = db.Column(db.String(40))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
#This is the stuff for scheduling, just date
hour = db.Column(db.Integer)
minute = db.Column(db.Integer)
day = db.Column(db.Integer)
month = db.Column(db.Integer)
year = db.Column(db.Integer)
ampm = db.Column(db.String(2))
Just as a test, I wanted to iterate over the current user's posts and tweet them using tweepy:
#app.before_first_request
def activate_job():
def run_job():
posts = current_user.followed_posts().filter_by(socialnetwork ='Twitter')
for post in posts:
tweepy_api.update_status(message)
time.sleep(30)
thread = threading.Thread(target=run_job)
thread.start()
However, this returned the error:
AttributeError: 'NoneType' object has no attribute 'followed_posts'
on the terminal. This is perplexing me as I have used current_user multiple times in the same file to filter the posts by social network.
As in the following case in routes.py
#app.route('/<username>')
#login_required
def user(username):
user = User.query.filter_by(username = username).first_or_404()
socialnetwork = request.args.get("socialnetwork")
if socialnetwork == 'Facebook':
posts = current_user.followed_posts().filter_by(socialnetwork = 'Facebook')
elif socialnetwork == 'Twitter':
posts = current_user.followed_posts().filter_by(socialnetwork = 'Twitter')
else:
posts = current_user.followed_posts()
return render_template('user.html', user = user, posts = posts, form = socialnetwork)
The above yields no error and works perfectly.
If anyone could shed some light on what I am doing wrong, I'd be truly grateful.
You're likely running into issues because you're trying to get current_user on a different thread (see the Flask docs for more details). You're calling run_job() in a different context that doesn't have any current user (because there's no active request).
I'd rework it so that you get the current user's posts on the main thread (i.e. in activate_job(), then pass the list of posts to the background process to work on.
Something like:
def activate_job():
posts = current_user.followed_posts().filter_by(socialnetwork ='Twitter')
def run_job(posts):
for post in posts:
tweepy_api.update_status(message)
time.sleep(30)
thread = threading.Thread(target=run_job, args=[posts])
thread.start()
It's also worth noting that you may want to rethink your overall approach. Rather than checking with each request if there are any scheduled tweets to send, you should use some sort of background task queue that an operate independently of the web process. That way, you're not checking redundantly on each request, and you're not dependant on the user making requests around the scheduled time.
See The Flask Mega-Tutorial Part XXII: Background Jobs for more details, and look into Celery.
In my site, the buyer search for a product and once he found it he can contact the seller by pressing on a contact button. If the conversation between the two concerning this product exists he should be redirected to the existing conversation, else, we create a new conversation.
The conversation is hence defined by two users and a listing.
When I try to implement the logic, I am not able to verify both conditions of the existance of the conversation, if the listing exists OR the users exists Django returns that the conversation exists. Here is my code:
def create_conversation(request, user_pk1, user_pk2, results_pk):
user1 = get_object_or_404(get_user_model(), pk=user_pk1)
user2 = get_object_or_404(get_user_model(), pk=user_pk2)
results= get_object_or_404(Listing, pk=results_pk)
existing_conversation = Conversation.objects.filter(users__in=[user1, user2]).filter(listing=results).values_list('id', flat=True)
if existing_conversation.exists():
return HttpResponseRedirect(reverse('conversation:conversation_update', kwargs={'pk':existing_conversation[0]}))
else:
conv=Conversation()
conv.save()
conv.listing = results
conv.save()
conv.users.add(*[user1,user2])
return HttpResponseRedirect(reverse('conversation:conversation_update', kwargs={'pk': conv.pk}))
Here is the model of the conversation:
class Conversation(models.Model):
"""
Model to contain different messages between one or more users.
:users: Users participating in this conversation.
:archived_by: List of participants, who archived this conversation.
:notified: List of participants, who have received an email notification.
:unread_by: List of participants, who haven't read this conversation.]\['
listing: the listing the conversation is about.
read_by_all: Date all participants have marked this conversation as read.
"""
users = models.ManyToManyField(
settings.AUTH_USER_MODEL,
verbose_name=_('Users'),
related_name='conversations',
)
# review the listing before going online, because it is necessary to have a conversation listing
listing = models.ForeignKey (
Listing,
verbose_name=_('Listing'),
related_name='listing',
default= 1,
)
and the model of the listing:
class Listing(models.Model):
seller = models.ForeignKey(Profile, related_name='seller_listing', verbose_name='sellr', limit_choices_to={'is_seller': True})
location_Country = models.CharField(max_length=45, verbose_name=_('from_Country'))
location_State = models.CharField(max_length=45, verbose_name=_('from_State'), null=True, blank=True)
location_City = models.CharField(max_length=45, verbose_name=_('from_City'))
I also tried an approach of divinding it into two conditions: a = conversation.objects.filter(users) and b= conversation.objects.filter(listing), then use if a and b then the conversation exists but got the same issue.
and existing_conversation = Conversation.objects.filter(Q(users__in=[user1, user2]) & Q(listing=results)).values_list('id', flat=True) but got the same issue. Thank you in advance for your help.
You can use intersection() method of django, added since Django 1.11, operator to return the shared elements of two or more QuerySets or the bitwise operation AND used with the sign `& to get the same behavior.
So in your case, check whether there's an intersection between the two users with & or intersection()
existing_conversation = (user1.conversations.all() & user2.conversations.all()).filter(listing=results)
# or with django intersection
existing_conversation = (user1.conversations.all().intersection(user2.conversations.all())).filter(listing=results)
if existing_conversation.exists():
return HttpResponseRedirect(reverse('conversation:conversation_update',
kwargs={'pk':existing_conversation.first().pk}))
else:
# rest of the code
BONUS, I see a typo in your code, you didn't send the pk as argument:
kwargs={'pk':existing_conversation[0]}
get the first instance with first() and get the pk
kwargs={'pk':existing_conversation.first().pk}
or
kwargs={'pk':existing_conversation[0].pk}
I'm matching the name in Album Model. And Its working just fine. But Some time It does not match. And It raise error message Album matching query does not exist. I want if no match is found. Then don't display any error message. Is it possible? Thanks
def movie_details(request,slug):
movies = get_object_or_404(Movie,slug=slug)
# calculating wikipedia directory structer for images
#image_name = movies.image
name = movies.title
album_name = Album.objects.get(name__exact=name)
album_id = album_name.id
song_list = Song.objects.filter(album=album_id)
#image_path = generateWikiImage(image_name)
#
return render_to_response('base_movies.html',locals(),
context_instance=RequestContext(request)
)
Error message
Album matching query does not exist
UPDATE:
def movie_details(request,slug):
movies = get_object_or_404(Movie,slug=slug)
# calculating wikipedia directory structer for images
#image_name = movies.image
name = movies.title
try:
album_name = Album.objects.get(name__exact=name)
album_id = album_name.id
song_list = Song.objects.filter(album=album_id)
except:
pass
Thanks F.C.
As suggested in the comment above, you need to catch the exception that's raised. In your case, it'd be:
try:
album_name = Album.objects.get(name__exact=name)
except Album.DoesNotExist:
pass
If you want to set album_name to some default value if you can't find it, replace pass with code to set it to your default value.
(This StackOverflow post also deals with a similar issue.)
I have a a form in Django with two inline forms. One of them is giving me grief.
My model is like so.
class BookingActivity(models.Model):
booking = models.ForeignKey('Booking')
program = models.ForeignKey(Program)
activity = models.ForeignKey(Activity, choices=programs_as_optgroups())
the activity ForeignKey choices are generated via this method:
def programs_as_optgroups():
activities = []
programs = []
for program in Program.objects.all():
new_program = []
new_activities = []
for activity in Activity.objects.filter(program=program):
new_activities.append([activity.id, activity.name])
new_program = [program.name, new_activities]
activities.append(new_program)
return activities
I'm trying to add <optgroup> tags to my ForeignKey select which is working. But when I submit the form I get an error: Cannot assign "u'3'": "BookingActivity.activity" must be a "Activity" instance.
This makes some sense - sort of. But if I check the request data sent from the form post. With choices either setup or not I get the same values, i.e.
activity = models.ForeignKey(Activity, choices=programs_as_optgroups())
and
activity = models.ForeignKey(Activity)
both return the a u'3' from the form. But I can't figure out why I get an error only when I'm using the optgroups.
I'm guessing you're trying
http://dealingit.wordpress.com/2009/10/26/django-tip-showing-optgroup-in-a-modelform/
in the blog
sub_categories.append([sub_category.id, sub_category.name])
you have
new_activities.append([activity.id, activity])
I think you're assuming you will get an object when it actually is a string you're getting back.