Shawn Mike
Shawn Mike

Reputation: 31

Getting one to many result

I am doing some trial and error in my django query. I'm trying to get a field with one column value beside it contains lists of elements. Basically I'm trying to figure out how to attain this result:

{
  feed: {},
  [{
   id: 1,
   media_id: 11
  }, {
   id: 2,
   media_id: 22
  }]
}

I tried in python shell this query and it gave me this result:

>>> query = Feed.objects.filter(Q(feedmedia__isnull=True)|Q(feedmedia__isnull=False)).values('message','feedmedia__id','feedmedia__media_id').distinct()

>>> print(query)


<FeedQuerySet [{'message': 'Classic motorcycles <3', 'feedmedia__id': 145, 'feedmedia__media_id': 152}, {'message': 'sample video', 'feedmedia__id': 147, 'feedmedia__media_id': 153}, {'message': 'Classic motorcycles <3', 'feedmedia__id': 146, 'feedmedia__media_id': 151}]>

On the result I understand why the 'message' (one of the field in Feed table) is included, and the problem is that I don't know how I'm going to exclude it in order to get the desired output.

These are the three models involved on this operation:

class Media(models.Model):
   original_url = models.CharField(max_length=200, null=False, unique=False)
   small_url = models.CharField(max_length=200, null=True, unique=False)
   medium_url = models.CharField(max_length=200, null=True, unique=False)
   large_url = models.CharField(max_length=200, null=True, unique=False)
   uploaded_at = models.DateTimeField(auto_now_add=True)

   class Meta:
     db_table = "media"


class Feed(models.Model):
   message = models.CharField(max_length=3000, null=True, unique=False)
   type = models.CharField(max_length=50, null=False, unique=False)
   category = models.CharField(max_length=50, null=False, unique=False)
   priority_level = models.IntegerField(default=0, null=False, unique=False)
   origin_location = models.CharField(max_length=100, null=True, unique=False)
   created_at = models.DateTimeField(auto_now_add=True)

   objects = FeedManager()

   class Meta:
     db_table = 'feed'


# Junction Table for Feed and Media
class FeedMedia(models.Model):
"""Model to represent gosam posts/feeds."""

   media = models.ForeignKey(Media, on_delete=models.CASCADE, null=False)
   feed = models.ForeignKey(Feed, on_delete=models.CASCADE, null=False)
   creator = models.ForeignKey(Profile, on_delete=models.CASCADE, null=False)

   objects = FeedMediaManager()

   class Meta:
     db_table = 'feed_media'

Upvotes: 0

Views: 225

Answers (3)

Leandro L
Leandro L

Reputation: 171

You can write serializers for each model, then set the specific field you want to use

class FeedSerializer(serializers.ModelSerializer):
   class Meta:
       model = Fedd
       fields = '__all__' # for all fields
       fields = ('field_1', 'field_1', 'field_1') # for specific fields

then in apiviews

class MyFilterView(APIView):
    def get(self, request)
         filter_data = Feed.objects.filter()#your filter
         serializer = FeedSerializer(filter_data, many=True) # many=True if are many results
         return Response(serializer.data)

Upvotes: 0

ruddra
ruddra

Reputation: 51988

If you are using django rest framework, then simply create a serializer like this:

class FeedMediaSerializer(serializer.ModelSerializer):
    class Meta:
       model = FeedMedia
       fields = ["id", "media_id"]


class FeedSerializer(serializer.ModelSerializer):
    media = FeedMediaSerializer(source="feedmedia", read_only=True)

    class Meta:
        model = Feed
        fields = ["message", "media"]

And try like this Python shell:

>> query = Feed.objects.filter(Q(feedmedia__isnull=True)|Q(feedmedia__isnull=False))
>> FeedSerializer(query, many=True).data

Upvotes: 0

wfehr
wfehr

Reputation: 2225

You didn't define a custom related_name in your ForeignKey fields of FeedMedia.

So your default reverse relation accessor would be <model_name>_set, e.g. feedmedia_set.

So if you want to access a Media object over FeedMedia from Feed, it would be the following:

query = Feed.objects.filter(Q(feedmedia_set__isnull=True)|Q(feedmedia_set__isnull=False)).values('message','feedmedia_set__id','feedmedia_set__media_id').distinct()

Upvotes: 1

Related Questions