Reputation: 31
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
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
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
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