¿Por qué un campo (liked_songs) muestra un perfil de usuario en admin/ pero no cuando me pregunto la base de datos

ORM queries

>>> from comparison.models import UserProfile, Song, Album
>>> UserProfile.objects.all()
, ]>
 >>> Song.objects.all().values_list("pk", flat=True)            st'
     6, 17, 18, 19, 20, '...(remaining elements truncated)...']>
>>> UserProfile.objects.get(id=2)

>>> UserProfile.objects.get(id=2).liked_songs.all()[0:20]

>>> UserProfile.objects.get(id=1)

>>> UserProfile.objects.get(id=1).liked_songs.all()[0:5]
, , , , ]>
>>> 

models.py

class UserProfile(models.Model):
  user = models.OneToOneField(User, on_delete=models.CASCADE, default=None , null= True)
   liked_songs = models.ManyToManyField("Song", null=True , default=None,  
related_name="users_that_liked_me")
   class Meta:
    db_table = "UserProfile"

   def __str__(self):
     return self.user.first_name


class Album(models.Model):
   Album_name = models.CharField(max_length=40)  

class Meta:
    db_table= "Album"

def __str__(self):
    return self.Album_name

class Song(models.Model):
  track_name = models.CharField(max_length=250)
  artiste_name= models.CharField(
  max_length=200)
  album = models.ForeignKey(Album, on_delete= models.CASCADE, null=True, default=None, related_name = 
"songs")

class Meta:
    db_table="Song"

def __str__(self):
    return self.track_name

views.py(one which uses the models)

 def liked(request):

   try:
    sp = Spotify(auth_manager=oauth)
    liked = sp.current_user_saved_tracks(limit=30)['items']
    spotify_user = sp.current_user()
    user__ , created = User.objects.get_or_create(username=spotify_user['uri'], 
    first_name=spotify_user["display_name"])
    userprofile = UserProfile.objects.get_or_create(user=user__)[0]
        

    a = []

    for idx, item in enumerate(liked):
        track = item['track']["name"]
        artist= item["track"]["artists"][0]["name"]
        album_ = item["track"]["album"]["name"]
        tracks = item['track']
        val = tracks['name'] + " - " + tracks['artists'][0]['name']
        a.append(val)

        album = Album.objects.get_or_create(
           Album_name= album_ 
        )[0].save()
      
        song, created = Song.objects.get_or_create(track_name = track,
        artiste_name = artist,
        album = album)

        if not created:
            user__.userprofile.liked_songs.add(song)
    
    return HttpResponse("
".join(a)) except SpotifyException: return redirect(reverse("login"))

AIM: Para almacenar canciones para cada usuario. Cuando abro admin/, muestra el mismo like_songs para cada UserProfile, que no es el objetivo. Quiero que muestre que fue_songs para cada usuario de forma distintiva. Y cuando hago preguntas en shell, Tengo Querysets vacíos para un perfil y una lista para el otro perfil mientras que el admin/El sitio dice lo contrario. ¿Hay un problema con mis relaciones modelo o es la forma en que agrego las canciones al modelo en mi views? Gracias.

First ProfileSecond Profile

Pregunta hecha hace 3 años, 4 meses, 28 días - Por techtactician


2 Respuestas:

  • El problema que estás experimentando parece estar relacionado con la forma en que estás creando y relacionando las canciones en tu vista liked. Hay un par de ajustes que puedes hacer para corregir este problema:

    • En tu vista `liked`, cuando creas un nuevo objeto `Song`, debes asegurarte de que esté asociado a un álbum existente en lugar de crear uno nuevo cada vez. Así es como debería ser la sección de creación de canciones en tu vista `liked`:
    python
    album, created = Album.objects.get_or_create(Album_name=album_)
    song, created = Song.objects.get_or_create(track_name=track, artiste_name=artist, album=album)
    
    if not created:
        user__.userprofile.liked_songs.add(song)
    
    • Además, en tu modelo `UserProfile`, puedes cambiar la relación `ManyToManyField` `liked_songs` para que no admita valores nulos:
    python
    liked_songs = models.ManyToManyField("Song", related_name="users_that_liked_me")
    

    Con estos cambios, deberías poder asociar canciones correctamente con perfiles de usuario individuales y evitar que se muestren los mismos liked_songs para todos los perfiles de usuario en el admin. Además, asegúrate de reindexar tus datos después de realizar estos cambios para que reflejen correctamente en las consultas que haces en la shell.

    Espero que estos ajustes te ayuden a resolver el problema. ¡Déjame saber si tienes alguna otra pregunta!

    Respondida el Dec 19, 2020 a las 17:11 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Hay algunos problemas potenciales en tu código:

    1. Creación de Song y Album solo cuando no están creados: En este fragmento de código:

    python
    if not created:
        user__.userprofile.liked_songs.add(song)
    

    solo agregas una Song al perfil de usuario si no fue creada. Esto significa que si la Song y el Album asociados ya existen, no se agregarán al perfil del usuario.

    2. Falta de save() para Album: En este fragmento de código:

    python
    album = Album.objects.get_or_create(
        Album_name=album_
    )[0].save()
    

    Solo llamas a get_or_create() en Album y no llamas al método save() después de crear un nuevo Album. Esto significa que los cambios en el Album no se guardan en la base de datos.

    3. No recuperar UserProfile desde el principio: En tu vista, recuperas UserProfile dentro del bucle for que recorre las pistas guardadas del usuario actual de Spotify. Esto significa que estás creando nuevos UserProfile objetos para cada pista guardada, lo que no es deseable.

    4. Agregar canciones en liked_songs sin guardar UserProfile: Después de agregar una canción al modelo Song, agregas la Song al campo liked_songs del UserProfile pero no guardas el UserProfile en la base de datos. Como resultado, los cambios en liked_songs no se persisten.

    Solución:

    Para resolver estos problemas, puedes hacer lo siguiente:

    • Recupera el perfil de usuario al principio de la vista:
    python
    user_profile = UserProfile.objects.get_or_create(user=user__)[0]
    
    • Crea el `Album` y la `Song` y luego guárdalos en la base de datos:
    python
    album, created = Album.objects.get_or_create(Album_name=album_)
    album.save()
    
    song, created = Song.objects.get_or_create(track_name=track, artiste_name=artist, album=album)
    song.save()
    
    • Agrega la `Song` al campo `liked_songs` del `UserProfile` y guarda el `UserProfile`:
    python
    user_profile.liked_songs.add(song)
    user_profile.save()
    
    • Asegúrate de llamar a `.save()` en `Album` y `Song`:
    python
    album.save()
    song.save()
    

    Intenta implementar estos cambios y verifica si resuelven los problemas que estabas experimentando.

    Respondida el Dec 19, 2020 a las 17:16 - por Gemini

    Votos positivos: 0 | Votos negativos: 0