Django view fetching data from two models in a single query - django

I have two tables in my database which are relevant for this problem:
exercise_state with following fields:
| id | intensity_level | progress | exercise_id | user_id | current_date | user_rating |
auth_user with following fields:
| id | password | last_login | is_superuser | username | first_name | last_name | email | is_staff | is_active | date_joined |
Right now I am fetching some data in my view as follows:
def get_specific_exercise_finish_count(request, exerciseId):
# Number of users who completed a specific exercise
specific_exercise_finish_count = Exercise_state.objects.filter(exercise_id=exerciseId, intensity_level=7).count()
data = {}
data['count'] = specific_exercise_finish_count
return JSONResponse(data)
Now I want to filter those results further for specific set of usernames i.e. usernames those starts with 'yg_' (I have two sets of usernames registered in my system one group starts with 'yg' and the other with 'yg_'). As username is not a field of exercise_state, I am not sure how to proceed.
How can I achieve this?

I solved it with following code of piece, see the extra part in filter statement:
def get_specific_exercise_finish_count_memoryGames(request, exerciseId):
# Number of users who completed a specific exercise
specific_exercise_finish_count_memoryGames = Exercise_state.objects.filter(exercise_id=exerciseId, intensity_level=7, user__username__startswith='yg_').count()
data = {}
data['count'] = specific_exercise_finish_count_memoryGames
return JSONResponse(data)

Related

Do an INSERT INTO a User table has been "extended" using django.contrib.auth.models import AbstractUser

I've cloned a Django/Angular Application and built it. The data migrations produced an empty database. I'm now attempting to set up a way to login as there is no account setup on the login page. The use of the AbstractUser is supposed to require that an email is required in place of a user name.
Trying to find a way to set up the login.
The User model is:
class User(AbstractUser):
email = None
first_name = None
last_name = None
REQUIRED_FIELDS = []
def __str__(self):
return self.email
class Meta:
db_table = 'User'
Table Description is:
Table "public.User"
Column | Type | Collation | Nullable | Default
--------------+--------------------------+-----------+----------+------------------------------------
id | integer | | not null | nextval('"User_id_seq"'::regclass)
password | character varying(128) | | not null |
last_login | timestamp with time zone | | |
is_superuser | boolean | | not null |
username | character varying(150) | | not null |
is_staff | boolean | | not null |
is_active | boolean | | not null |
date_joined | timestamp with time zone | | not null |
Using this description I've attempted to some add data to facilitate being able to log in.
select * from "User";
id | password | last_login | is_superuser | username | is_staff | is_active | date_joined
----+--------------+------------+--------------+----------+----------+-----------+------------------------
1 | blankDon012! | | t | donfox1 | t | t | 2021-11-12 00:00:00-05
Not able to insert an email address. Articles on internet seem to not quite address this issue so far.

Linking one table to each user in Django

I am working on a Django project where I need to link one table(model) to each user.
Assume MyTable_1 maps to user_1 and so on.
The primary key for MyTable will be a DateField which contains continuous dates from the time user signed-up.
MyTable_1 for User_1
|-----------|----------|-------------|-----------------|
| Date(PK) | food_ate | game_played | ran_today |
|-----------|----------|-------------|-----------------|
| 10/01/20 | rice | chess | Yes |
|-----------|----------|-------------|-----------------|
| 11/01/20 |sandwhich | tennis | No |
|-----------|----------|-------------|-----------------|
MyTable_2 for User_2
|-----------|----------|-------------|-----------------|
| Date(PK) | food_ate | game_played | ran_today |
|-----------|----------|-------------|-----------------|
| 16/03/19 | pizza | rugby | Yes |
|-----------|----------|-------------|-----------------|
| 17/03/19 | pasta | football | Yes |
|-----------|----------|-------------|-----------------|
And so on for every new user created. User logs in those information in MyTable.
How can I implement this? I am using PostgreSQL and have written custom User Model.
You really don't need seperate tables just seperate rows.
A ForeignKey relation will do the trick, something like this in your models.py:
# user model:
User(models.Model, ...):
first_name = models.CharField(...)
last_name = models.CharField(...)
...
# log model:
Log(models.Model):
user = models.ForeignKey(User, ...)
date = models.DateField(...)
food_ate = models.CharField(...)
game_played = models.CharField(...)
ran_today = models.CharField(...)
class Meta: unique_together = ('user', 'date',)
Then, elsewhere, you can access your users' logs like so:
user = User.objects.get(id='the_user_id')
logs = user.logs.all()

Django reading data from 2 models with foreignkey and make single list

I'm new to django. I've been coding with sql but django orm is hard for me to convert my knowledge of sql to orm models.
I've client model
class client(models.Model):
c_id = models.AutoField(primary_key=True)
name= models.TextField()
age=models.IntegerField()
and address model
class address(models.Model):
c_id = models.ForeignKey(client, on_delete=models.CASCADE)
addr = models.CharField(max_lenght=20)
city= models.CharField(max_lenght=20)
This is my table
---------------------------
| c_id|Name | age |
---------------------------
| 1 | John | 23 |
----------------------------
| 2 | Rose | 20 |
----------------------------
------------------------------
| c_id|addr | city |
------------------------------
| 1 | buspark | florida|
------------------------------
| 2 | homesquare| florida|
------------------------------
how to get allclient with address in list
Look at values() docs
The values() method takes optional positional arguments, *fields,
which specify field names to which the SELECT should be limited. If
you specify the fields, each dictionary will contain only the field
keys/values for the fields you specify. If you don’t specify the
fields, each dictionary will contain a key and value for every field
in the database table.
__ allows get related data, so in your case it could look like this
address.objects.values('c_id__c_id', 'c_id__name', 'c_id__age', 'addr', 'city')

How to add any number of users to the same table in postgres?

I am using postgres and django and I have a table defined below in postgres
Column | Type | Modifiers
---------------------+------------------------+-----------
id | integer |
context_name | character varying(100) |
context_description | character varying(100) |
context_priority | character varying(1) |
users | integer |
Below is the associated model in django
class Contexts(models.Model):
context_name = models.CharField(max_length=50)
context_description = models.TextField()
context_priority = models.CharField(max_length=1)
users = models.PositiveIntegerField(null=False)
Note: I cannot run makemigrations since I have some issues in the settings.So I create the table manually in postgres and define the associated model in django.
Now this table is basically a group context_name which can have many users.So I receive a JSON request and add the user to the table.Below is the JSON
{
"user" : 5,
"action" : "add",
"context_name": "network debug",
"context_description" : "Group for debugging network issues",
"context_priority": "L"
}
Here is the code that handles the operation
#csrf_exempt
def context_operation(request):
user_request = json.loads(request.body.decode('utf-8'))
if request.method == "POST":
try:
if user_request.get("action") == "add":
conv = Contexts.objects.create(
context_name=user_request.get("context_name"),
context_description=user_request.get("context_description"),
context_priority=user_request.get("context_priority"),
users=user_request.get("user")
)
#print(conv.users)
except Exception as e:
print("Context saving exception", e)
return HttpResponse(0)
return HttpResponse(1)
Now when I run this code and a request comes in, I can save the user 5 in the group network debug successfully but if I receive the same request again but with a different user id 7, it creates the same group again and assigns user 7.So I have two same groups but different users.
How do I ensure as long as the the context_name is same, I can add any number of users?
You can have two different models as below.
class Contexts(models.Model):
context_name = models.CharField(max_length=50)
context_description = models.TextField()
context_priority = models.CharField(max_length=1)
class ContextUsers(models.Model):
context = models.ForeignKey('Contexts', null=False)
user = models.PositiveIntegerField(null=False)
Whenever a new context is received, create one, else assign the existing context and make an entry to the ContextUser. So, for multiple users with the same contexts you will have tables as below:
Context
id | context_name | context_description | context_priority
1 | c1 | some descriptions | a
2 | c2 | some other descr. | b
ContextUsers
context_id | user
1 | 1
1 | 2
1 | 3
2 | 1
2 | 4

Django join on multiple foreign fields (left join)

I'm using django 1.10 and have the following two models
class Post(models.Model):
title = models.CharField(max_length=500)
text = models.TextField()
class UserPost(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
approved = models.BooleanField(default=False)
How do I get a list of all the posts including the 'approved' property for the logged in user if exists? So instead of multiple queries, it would be one left join query, pseudo-code:
select * from posts as p
left join user_posts as up
on up.post_id = p.post_id
and up.user_id = 2
Output
post_id | title | text | user_id | approved
1 | 'abc' | 'abc' | 2 | true
2 | 'xyz' | 'xyz' | null | null
3 | 'foo' | 'bar' | 2 | true
I created the models this way because the 'approved' property belongs to the user. Every user can approve/reject a post. The same post could be approved and rejected by other users. Should the models be setup differently?
Thanks
Update:
I'm trying to create a webpage to display all available posts and highlight the ones that the current user approved. I could just list all posts and then for each post check if the 'UserPost' table has a value, if yes get the approved property else ignore. But that means if I have 100 posts I'm making 100 + 1 calls to the db. Is it possible to do 1 call using ORM? If this is not possible, should the models be setup differently?
Then I think you need something like this:
Post.objects.all().annotate(
approved=models.Case(
models.When(userpost_set__user_id=2,
then=models.F('userpost__approved')),
default=models.Value(False),
output_field=models.BooleanField()
)
)