I want to perform this query to get the id of all the groups that are associated with the table auth_group_permissions.
select id from auth_group where id in (select group_id from auth_group_permissions group by group_id)
Models Group and Permission are connected to each other via ManyToMany field permissions. See the source
Based on the info I found in internet and based on what I remember, you need to do the next:
from django.contrib.auth.models import Group, Permission
grouped_permissions = Permission.objects.order_by().distinct('group_id')
your_ids = Group.objects.filter(permissions__group_id__in=grouped_permissions).values_list('id', flat=True)
That's the final correct answer.
grouped_permissions = Permission.objects.filter().order_by().distinct().values_list('group__id',flat=True)
your_ids = Group.objects.filter(id__in = grouped_permissions)
Related
I'm trying to filter out a ModelForm to only display dropdown values tied to a specific user.
I've got three tabled tied together:
User, Project, ProjectUser.
One user can have many projects, and one projects can have many users, and the table ProjectUser is just a joined table between User and Project, e.g
id | project_id | user_id
1 5 1
2 6 2
3 6 1
How would I write the following inner join query in Django ORM?
SELECT name
FROM projectuser
INNER JOIN project
ON projectuser.project_id = project.id
WHERE user_id = <request.user here>
When Django ORM applies a Filter to a field specified as a foreign key, Django ORM understands that it is a related table and joins it.
Project.objects.filter(projectuser__user=user)
You can join multiple tables, or even apply a filter to the reverse of a foreign key! You can use the related_name of the ForeignKey field appropriately.
You original SQL
SELECT name
FROM projectuser
INNER JOIN project
ON projectuser.project_id = project.id
WHERE user_id = <request.user here>
So as i see your SQL, you want to get list of name from projectuser for specific user. If so, here is the answer
ProjectUser.objects.filter(user_id = user).values_list('name', flat = True)
I see you accept answer with Project.objects.filter(projectuser__user=user)
For this answer your SQL should look like this
SELECT name
FROM project
INNER JOIN projectuser
ON projectuser.project_id = project.id
WHERE projectuser.user_id = <request.user here>
Task Details
I am working on creating a custom API to fetch data from three tables, based on provided key info.
Background
To elaborate, I've three data tables - Client, Account and Client_accounts and their structure looks like this:
Client
ID (Integer) Primary Key
display_name (varchar)
Accounts
ID (Integer) Primary Key
nickname (varchar)
Client_Accounts
Client_ID (Integer) Foreign Key -> ID from client table
Account_ID (Integer) Foreign Key -> ID from accounts table
In intend to pass a client ID to my API and want to fetch all the accounts (and accounts names) owned by that client.
The SQL query that I am trying to replicate looks like this:
select
cl.id as client_id,
cl.display_name,
ac.id as account_id,
ac.nickname as account_name
from
datahub_clients cl
join
datahub_client_accounts cl_ac
on
cl.id=cl_ac.client_id
join
datahub_accounts ac
on
cl_ac.account_id=ac.id
where
cl.id=15
;
Done so far
This is what I used to fetch the the accounts for a client:
##### For endpoint - get_client_name
#api_view(['GET', 'POST'])
#permission_classes((AllowAny,))
def get_client_name(request):
try:
if request.method == 'GET':
list_of_account_ids = Client_Accounts.objects.filter(client_id=request.GET['id']).values_list('account')
needed_accounts = Accounts.objects.filter(id__in=list_of_account_ids).values('id','nickname')
return Response({'requested client id':request.GET['id'],'identified client name': 'detailed info to go here'}, status=status.HTTP_200_OK)
else:
return Response({'status':'error','message': 'Facepalm moment!'}, status=status.HTTP_403_FORBIDDEN)
Problem Statement
1) In the code above, I was able to pull the relevant accounts for a client_id, however, I can only print the details from account table. How do I put client information as well in the output (client_id, nickname - as shown in the SQL query)
2) What is the django replacement for SQL 'old_field_name AS some_new_name'? In the data tables shown above, both the account and client tables have an 'ID' column. I want to put them both together in the same JSON output and to be able to distinguish between then, I would want to rename them.
3) At this point, my queryset has field members from multiple models. How do I serialize them? I understand that I need to write a custom serializer, which would be based on the two models (for the example show above). I am confused about what to specify in the model= section and meta: section.
Python 3.6 / Django 2
I have a Profile model that defines and "extended" User model. I have a Group model that defines some internal, app related groups; and, a ProfileGroupLink model that defines the possible group(s) a profile might belong to.
Let's say the tables look like:
Profile
----------
id int
name_last varchar(32)
name_first varchar(32)
account_number uuid
Group
----------
id uuid
name varchar(32)
ProfileGroupLink
----------
id int
groupLnk uuid foreign key(Group.id)int
profileLnk uuid foreign key(Profile.account_number)
I have the active user "profile" from:
my_profile = Profile.objects.get(user=request.user)
I would normally write an SQL query something like:
select Group.name
from Group as Group
inner join Profile as Profile
on ? = Profile.id
inner join ProfileGroupLink as ProfileGroupLink
on Profile.id = ProfileGroupLink.profileLnk
and Group.id = ProfileGroupLink.groupLnk
order by Group.name
and pass the profile id in as a parameter. I am looking at the page: https://docs.djangoproject.com/en/2.0/topics/db/queries/ but I am not getting the double underscore syntax for joins.
My current attempt is:
groups = Group.objects.all() \
.filter(GroupList__profile=my_profile.account_number) \
.filter(GroupList__group=Group__group_id)
but PyCharm flags "Group__group_id" as an unresolved reference. I am importing the models. How do I do this in Django?
I'm going to assume that what you want to get the query is to obtain the groups that belong to a profile
groups = Group.objects.filte(profilegrouplink__profilelnk=my_profile)
note that I put everything in lowercase, do not need to put all the joins and do not use the models to make the filters, the attributes are used
I am used in creating orm and leaving django responsible for creating the tables.But in a project I am involved I have to create a simple CRUD application a frontend for an existing database. The database was created by creating the tables manually. So I have two tables Table1 and Table2 which have a many to many relationship through Tables12. Tables12 looks like the table that django would normaly create using a ManyToManyField thus it has two fields the id's of the two models. So after using django's inspectdb, django successfully created the models according to the SQLite database. The many to many tables like Tables12 was created like the following(as stated above):
class Tables12(models.Model):
table1 = models.ForeignKey(Table1)
table2 = models.ForeignKey(Table2)
class Meta:
managed = False
db_table = "Tables12"
unique_together = (("table1_id", "table2_id"),)
Trying the following gives me an error:
>> table2 = Table2.objects.get(pk=1)
>>tables12 = Tables12.objects.filter(table2=table2)
>>tables12
OperationalError: no such column: Tables12.id
I am guessing Django's orm is expecting an id field in every models created. How can I bypass this behavior? Is there a way to edit the tables so as they look more like django's orm but behave as the existing db's tables? Like:
class Table1(models.Model):
#pre exsiting fields
table2 = models.ManyToManyField(Table2)
or
class Table2(models.Model):
#pre existing fields
table1 = models.ManyToManyField(Table1)
but without destroying database records and without creating tables from start.
You can remove the Tables12 model, and specify the db_table argument to a ManyToManyField:
class Table1(models.Model):
tables2 = models.ManyToManyField(Table2, db_table='Tables12')
You would still not be able to query the Tables12 model directly (it still exists and has an id field), but this would allow you to use the JOINs Django generates for a ManyToManyField:
table1 = Table1.objects.get(pk=1)
tables2 = table1.tables2.all()
This would still not allow you to use Django to write to the join table, but it allows you to use the data that's in it. If at all possible, I'd strongly recommend adding a primary key.
I would like to know how to frame the following to the Django ORM form:
SELECT name,mobile_number,COUNT(*) as count, created FROM core_user,core_useractivity WHERE core_user.id = core_useractivity.user_id GROUP BY user_id ORDER BY count DESC;
where name, mobile number are columns in core_user table or USER model, and created is a column in core_useractivity its model is UserActivity . The two tables are joined on user_id. Further I am grouping the rows by user_id displaying the result in Descending order.
Try annotating the users with the user activity count.
from django.db.models import Count
User.objects.annotate(num_activities=Count('useractivity')).order_by('num_activities')
This will return a queryset of users, each with an attribute num_activities. See the docs on annotation for more information.