Une requête un peu compliquée

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous,

J'ai un projet à faire pour l'école, et j'ai décidé de le faire en Django. J'apprends sur le tas, et tout se passe plutôt bien pour l'instant, mais je me retrouve coincé bêtement devant une requête un peu plus compliquée que les autres… :(

Voici le MCD de l'application :

MCD

Je cherche à récupérer dans un QuerySet :

  • Tous les Events créés par un User donné (ça c'est facile) ;
  • Plus tous les Events pour lesquels ce User a une Invitation.

J'ai déjà la première partie, mais je n'ai aucune idée de la manière dont je vais m'y prendre pour l'autre partie… :euh: Voici ce que j'ai écrit pour l'instant :

1
2
3
response = []
for e in Event.objects.filter(fk_user_created_by=user.pk):
    response.append(e.json_detail())

Je ne sais pas ce que je peux fournir comme info supplémentaires… En tous cas, merci pour votre aide ! :)

Auteur du sujet

Bien sûr ! Les voilà :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class User(models.Model):
    first_name = models.CharField(max_length=50, null=True)
    last_name = models.CharField(max_length=50, null=True)
    password = models.CharField(max_length=50, null=False, blank=False) # On hashera plus tard
    email = models.EmailField(max_length=70, null=False, unique=True, blank=False)
    phone_number = models.CharField(max_length=15, null=True, unique=True)

class Event(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=250)
    date = models.DateTimeField()
    date_created = models.DateTimeField(auto_now_add=True)
    place_event = models.CharField(max_length=100)
    fk_user_created_by=models.ForeignKey(User, on_delete=models.SET_NULL, null=True)

class Invitation(models.Model):
    content = models.CharField(max_length=250)
    status = models.CharField(max_length=1, choices=(
        ('P', 'Pending'),
        ('A', 'Accepted'),
        ('R', 'Refused'),
        ), default='P')
    date_created = models.DateTimeField(auto_now_add=True)
    fk_event = models.ForeignKey(Event, on_delete=models.CASCADE)
    fk_user_created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='user_creator')
    fk_user_invited = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_invited')
    fk_rank = models.ForeignKey(Rank, on_delete=models.CASCADE)

EDIT : Une petite remarque, au cas où ça ne serait pas clair : Invitation.fk_user_created_by est l'utilisateur qui a créé l'invitation, Invitation.fk_user_invited est l'utilisateur qui est invité, et c'est cette clé-là qui m'intéresse.

Édité par Richou D. Degenne

Staff

Cette réponse a aidé l'auteur du sujet

Tous les Events créés par un User donné

ça doit donner quelque chose dans ce gout là :

1
2
3
4
5
from .models import Event

# en supposant que user est l'object de type User recherché

query = Event.objects.filter(fk_user_created_by.pk=user.pk)

Plus tous les Events pour lesquels ce User a une Invitation.

ça devrait donner ceci :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from .models import Event, Invitation

# en supposant que user est l'object de type User recherché

query = Event
  .objects
  .filter(pk__in=Invitation
    .objects
    .filter(fk_user_invited.pk=user.pk)
    .values_list('fk_event__pk', flat=True)
  )

Si tu veux obtenir les deux dans une seule Queryset finale tu passe donc par :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from django.db.models import Q
from .models import Event, Invitation

# en supposant que user est l'object de type User recherché

query = Event
  .objects
  .filter(Q(pk__in=Invitation
    .objects
    .filter(fk_user_invited.pk=user.pk)
    .values_list('fk_event__pk', flat=True))
    | 
    Q(fk_user_created_by.pk=user.pk)
  )

Édité par firm1

Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte