django related manager - get specific data - python

I am trying to get rate of the user who has written the comment.
this is the scenario:
I hold the comment about Something in my hand, I hold the user in my hand who wrote this comment Something. Now I need to know the rate which is given by the user to this Something.
these are my models:
class Rate(models.Model):
of_user_r = models.ForeignKey(User)
of_something_r = models.ForeignKey(Something)
rate = models.IntegerField()
class Comment(models.Model):
of_user_c = models.ForeignKey(User)
of_something_c = models.ForeignKey(Something)
i did: {{comment.of_user_c.of_user_r.rate}}, but I getting nothing in template.
this is the vusual:
I need the rate of this Something which is given by this User.

Yes, your attempt doesn't work because the relationship from User to Rate is backwards. This means you can't do that query directly in the template: you'd need a model method or a template filter that accepts arguments. The basic query syntax would be:
Rate.objects.filter(user=comment.user)

Related

Django .order_by() related field returns too many items

I'm trying to return a list of users that have recently made a post, but the order_by method makes it return too many items.
there is only 2 accounts total, but when I call
test = Account.objects.all().order_by('-posts__timestamp')
[print(i) for i in test]
it will return the author of every post instance, and its duplicates. Not just the two account instances.
test#test.example
test#test.example
test#test.example
test#test.example
foo#bar.example
Any help?
class Account(AbstractBaseUser):
...
class Posts(models.Model):
author = models.ForeignKey('accounts.Account',on_delete=models.RESTRICT, related_name="posts")
timestamp = models.DateTimeField(auto_now_add=True)
title = ...
content = ...
This is totally normal. You should understand how is the SQL query generated.
Yours should look something like that:
select *
from accounts
left join post on post.account_id = account.id
order by post.timestamp
You are effectively selecting every post with its related users. It is normal that you have some duplicated users.
What you could do is ensure that your are selecting distinct users: Account.objects.order_by('-posts__timestamp').distinct('pk')
What I would do is cache this information in the account (directly on the acount model or in another model that has a 1-to-1 relashionship with your users.
Adding a last_post_date to your Account model would allow you to have a less heavy request.
Updating the Account.last_post_date every time a Post is created can be a little tedious, but you can abstract this by using django models signals.

Django filtering: from a list of IDs

I'm using Django Rest Framework.
The model class is
class MyModel(models.Model):
id = models.CharField(max_length=200)
name = models.CharField(max_length=200)
genre = models.CharField(max_length=200)
And what I have set up so far is that, when the user does a POST request, the backend will take the request data and run a python script (which takes some parameters from the request data) which will in turn return a list of IDs corresponding to the "id" in MyModel. But the problem is, let's say I want to return only the ids that point to the model instances with genre "forensic", how do I do that?
I don't really have a clue how to do that, apart from doing a query on each id returned by the python script and filtering out the ones I want based on the genre returned from the query?
Maybe you can try like this:
MyModel.objects.filter(id__in=IDS, genre='forensic').values_list('id', flat=True) # assuming IDS come from the script

Referencing user object inside model method in Django

I have the following in my model:
class Genre(models.Model):
name = models.CharField(max_length=100)
def my_latest_song(self):
song = Song.objects.filter(genre_id=self.id, author_id=XXXXXXXXX).order_by('-date')
return song[0];
class Song(models.Model):
name = models.CharField(max_length=100)
genre = models.ForeignKey(Genre, on_delete=models.CASCADE, null=True)
date = models.DateField()
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
So with the my_latest_song method I want to obtain for each genre what the latest song is for the user currently logged in. Note: I am already making sure that users MUST be logged in to see this, do not worry about this additional validation.
The question is: how can I pass the user id of the user that is currently logged in onto this model method? Where the XXXXXXXXXX is listed I have tried:
author_id=request.user.id
author_id=user.id
author=request.user
author=user
And many similar options. But I'm new to Django and just not sure about how to properly reference this. Nothing is working yet.
Please note: the issue is that I am constantly (in many different views) displaying the latest song for each genre. So that's why I am thinking it makes sense in the model. It's not stored in a database, it's simply retrieved within the model. Please let me know if this is not appropriate.
For instance, on many pages I am showing a list of genres and for each genre the latest song uploaded by that user:
Genre | Last Song
----------------------
Pop | Song 1
Rock | Song 33
Classic | Song 32
Something like this maybe?
...
def my_latest_song(self, user_id):
song = Song.objects.filter(genre_id=self.id, author=User.objects.get(pk=user_id)).order_by('date')
return song[0];
...
You will not be able to use request.user.id or any other request value in that method, as the model does not actually use requests. That usually is done by a form.
You should not be making this query in your model. It is much better to make the query in views.py whenever you need the information.
Below is, if I understand correctly, what you would need to do to make this query in the view.
def relevant_view(request,genreID_from_url):
# ... #
song = Song.objects.filter(author=request.user).filter(genre=genreID_from_url).order_by('-date')[:1]
# ... #
A couple of points:
I think you would need to pass the genre you are querying for in the URL. Here is a good tutorial for that: http://django-book.readthedocs.io/en/latest/chapter03.html#your-third-view-dynamic-urls . You could also do it using a form - it depends on the circumstances in which the query needs to be made.
You need to order by '-date' and not 'date' so that you get the most recent song at the start of the query.
The [ ] at the end is Django's syntax for limiting a queryset. The above limits it to only the first item of the queryset, as you are attempting to do.
The page in the Django docs for queries is really helpful and clear: https://docs.djangoproject.com/en/2.0/topics/db/queries/

update multiple fields via filter for a django model

I have defined the following model:
class User(models.Model):
userid = models.CharField(max_length=26,unique=True)
coins = models.IntegerField()
points = models.IntegerField()
language = models.CharField(max_length=3)
Now I would like to run a filter query and update coins and points for all users matching my query.
However, I must have gotten something wrong, since field values won't get updated this way (I don't receive error messages):
User.objects.filter(language='en', points__gte=score).update(coins='100', points='10')
What is the correct way to update the fields for my selection?
Though the statements seem to be correct, but should pass integers instead of strings.
You can try this way:
users=User.objects.filter(language='en', points__gte=score)
Now,
for user in users:
user.coins = 100
user.points=10
user.save()
There is already a bultin model named User so you should try avoiding it as a model name.
You use update in a right way. But there might eventually a little problem in the following issue.
Your model has the fields:
coins = models.IntegerField()
points = models.IntegerField()
Do you notice something? They are integer fields.
Maybe you can try your statement again with this slight change:
User.objects.filter(
language='en', points__gte=score
).update(
coins=100, points=10
)
Pass integers and not strings!

How to create relations with django

This will be my first post here so I hope that everything will be correct.
I got some trouble with django, I try to make a little lottery game.
For this game I have one app called bitcoinlottery and in that app 2 models. As for now they look like this:
from django.db import models
from django.utils import timezone
class Lottery(models.Model):
owner = models.ForeignKey('auth.User')
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=110)
max_players = models.IntegerField()
total_players = models.CharField(default=0)
online = models.BooleanField(default=True)
create_date = models.DateTimeField(default=timezone.now)
class Ticket(models.Model):
owner = #this most be related to the user that buy the ticket
lottery_id = #this most be related to the id of the lottery
ticket_id = #a random number
Now I have two problems that I can't figure out.
The first one is how to create the number of tickets related on the Lottery max_players, the max_players will be a number of the maximum players/tickets available.
The second question is there a option to see all the available tickets in a list on the admin page of the lotteries?, and if yes, what is the way to do this.
Thanks for any help.
Have a nice day.
First of all I am not sure if your owner field would work. I don't see any imports for auth package
owner = models.ForeignKey('auth.User')
Firstly I would suggest you look at this post for changing that relation.
Both of your questions need a little bit more clarity regarding what you actually what to achieve. It would be helpful if the Ticket model is also completed.
For the given information its hard to say if that is possible looking there is no relation between both the models.
class Ticket(models.Model):
# This is not required unless you want it for some reason, you can use
# this owner from the lotter_id
owner = #this most be related to the user that buy the ticket
lottery_id = models.ForiegnKey(Lottery)
ticket_id = #a random number
def __str__(self):
return self.lottery_id, function_that_return_max_tickets()
Using the above relation you can write custom functions in the ModelManager, according to your requirement.
Read through the Mangers that Django provides, these can be used to write those functions which would calculate the max number of tickets and return if you like to use them in views.py using ORM.

Categories

Resources