Serializer remove parent field django - django

{
"episode": {
"id": 6,
"channel_id": 2,
"channel": {
"id": 2,
"tags": [
"new"
]
},
{
"episode": {
"id": 7,
"channel_id": 3,
"channel": {
"id": 2,
"tags": [
"new"
]
}
},
Hey I am new to Django. I am wondering how to remove episode parent written in the serializer response and directly go into the id, channel. Episode is not useful for me here. I have a model that sets the priority of these episodes. Have excluded the priority and id field but don't know how to remove episode parent.
class TrendingEpisode(models.Model):
episode = models.ForeignKey(Episode, null=False, blank=False, on_delete=models.CASCADE)
priority = models.IntegerField(null=False, blank=False)
class Episode(models.Model):
channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
tags = models.ManyToManyField(EpisodeTag)
#some other fields

Why do you use TrendingEpisode with foreignkey? Just use Episode only.
class Episode(models.Model):
channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
tags = models.ManyToManyField(EpisodeTag)
#some other fields
Then you can get your serialized data like below
{
"id": 6,
"channel_id": 2,
"channel": {
"id": 2,
"tags": [
"new"
]
},
}

Related

django-filters returns two the same models when an instance of a model has the same value

Here is my code;
models.py
class Home(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return str(self.user)
class GeneralHomeFeatures(models.Model):
home = models.ForeignKey(
Home, on_delete=models.CASCADE, related_name="general_home_features"
)
home_feature = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return str(self.home)
serializer.py
class GeneralHomeFeaturesSerializer(serializers.ModelSerializer):
class Meta:
model = GeneralHomeFeatures
exclude = ["home"]
filterset.py
class HomeFilter(filters.FilterSet):
home_feature = filters.CharFilter(field_name="general_home_features__home_feature", lookup_expr="icontains")
class Meta:
model = Home
fields = [
"home_feature",
]
once I give GeneralHomeFeatures class the same value twice, once filtered, it returns the same instance twice. Example; I make a request to this url - http://localhost:8000/api/homes/?home_feature=Pool and it returns this;
[
{
"id": 1,
"user": "cliffaust",
"general_home_features": [
{
"id": 1,
"home_feature": "Pool"
},
{
"id": 2,
"home_feature": "Children Play Ground"
},
{
"id": 7,
"home_feature": "Pool"
}
],
},
{
{
"id": 1,
"user": "cliffaust",
"general_home_features": [
{
"id": 1,
"home_feature": "Pool"
},
{
"id": 2,
"home_feature": "Children Play Ground"
},
{
"id": 7,
"home_feature": "Pool"
}
],
},
{
"id": 3,
"user": "cliffaust",
"general_home_features": [
{
"id": 4,
"home_feature": "Pool"
},
{
"id": 6,
"home_feature": "Children Play Ground"
}
],
}
]
because home_feature of GeneralHomeFeatures has two the same value(pool), it seems like django-filter is returning the same instance twice(based on the serializer id).
I don't know if this is a fault in my code, or its just how it works. Also, is they a better way of doing something like this?

Django serializers filter foreignkey

view:
class MPNView(viewsets.ModelViewSet):
queryset = MPN.objects.all()
serializer_class = MPNSerializer
serializers:
class ProductsSerializer(serializers.ModelSerializer):
class Meta:
model = Products
fields = "__all__"
class MPNSerializer(serializers.ModelSerializer):
products = ProductsSerializer(many=True)
class Meta:
model = MPN
fields = "__all__"
model:
class MPN(Model):
number = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
class Product(Model):
mpn = models.ForeignKey(to=MPN, on_delete=models.CASCADE, related_name="products", null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
Results i am getting:
[
{
"id": 1221,
"products": [],
"number": "B07BMTYSMR",
"created_at": "2020-09-29T03:05:01.560801Z"
},
{
"id": 1222,
"products": [
{
"id": 2352,
"created_at": "2020-09-30T12:49:09.347655Z",
},
{
"id": 2352,
"created_at": "2020-09-30T12:49:09.347655Z",
}
]
}
]
Results i am expecting:
[
{
"id": 1222,
"products": [
{
"id": 2352,
"created_at": "2020-09-30T12:49:09.347655Z",
},
{
"id": 2352,
"created_at": "2020-09-30T12:49:09.347655Z",
}
]
}
]
Here is my code . I have shared view, model and serializers.
Here I am trying to get result with ForeignKey related fields.
But, I want to add one filter so that it ignores data where products is [ ] (empty array)
Please have a look how can I achieve that.
Try filtering the queryset:
queryset = MPN.objects.all().exclude(products__isnull=True)
Here you would use the "products" and check if it is empty. Empty results would be excluded.

Django-Rest-Framework POST request to ManyToMany Field

I have a django model that is a message. It has a name which is a CharField, then also an array of users which is a ManyToManyField.
So This is what my API looks like:
[
{
"id": 13,
"content": "hej",
"date": "2019-07-09",
"sender": {
"id": 1,
"username": "william"
}
},
{
"id": 14,
"content": "hej william",
"date": "2019-07-09",
"sender": {
"id": 3,
"username": "ryan"
}
}
]
What I've tried to send via postman POST:
{
"content": "Hello",
"sender": {"username": "william"},
"date": "2019-09-02"
}
The Error I get:
sqlite3.IntegrityError: NOT NULL constraint failed: chat_message.sender_id
ManyToManyField(Userprofile=User):
class Message(models.Model):
sender = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name="sendermessage")
content = models.CharField(max_length=500)
date = models.DateField(default=date.today)
canview = models.ManyToManyField(UserProfile, blank=True, related_name="messagecanview")
class Meta:
verbose_name_plural = 'Messages'
def __str__(self):
return "{sender}".format(sender=self.sender)
Assuming that you have a MessageSerializer class implemented, you could override its create() method in order to support writable nested representations:
class MessageSerializer(serializers.ModelSerializer):
...
def create(self, validated_data):
sender_data = validated_data.pop('sender')
sender = UserProfile.objects.create(**sender_data)
return Message.objects.create(sender=sender, **validated_data)
You pop the sender data from the dictionary, create a UserProfile instance with the attributes in there and then attach it to your Message creation.
This will resolve your error since now there is a real sender created before the actual message has been saved.

How to serialize ForeignKey in Django rest?

I'm using the latest version of django rest framework.
I have this model:
class Subscriptions(models.Model):
subs_list = models.ForeignKey(SubsList, verbose_name='Subscription list', on_delete=models.CASCADE, related_name='subs_list') # идентификатор подписного листа
subscriber = models.ForeignKey(Subscribers, verbose_name='Subscriber', on_delete=models.CASCADE) # идентификатор подписчика
created_date = models.DateTimeField(verbose_name='Created date', auto_now=True) # дата добавления подписчика в подписной лист
deleted = models.NullBooleanField(verbose_name='Deleted') # True-удален из подписного листа, False/null-в подписном листе
How do I serialize it? The main question is how to serialize ForeignKey, that would be associated with the query related data, i.e. NOT:
"id": 29,
"created_date": "2018-03-01T14:28:41.237742Z",
"deleted": false,
"subs_list": 1,
"subscriber": 1
but like this
"id": 29,
"subs_list": {
"id": 1,
"uuid": "d183bab7-af26-48f8-9ef5-ea48e09a95a9",
"name": "TEST",
"description": "TEST",
"created_date": "2018-03-01T13:15:18.808709Z",
"deleted": null,
"user": 6
},
"subscriber": {
"id": 1,
"bot_id": "1",
"name_messenger": "11",
"username": "1",
"first_name": "1",
"last_name": "1",
"created_date": "9999-03-01T16:47:51.440000Z",
"subscribed": true,
"chat_bot": "1",
"phone": "1",
"user": 1
},
"created_date": "2018-03-01T14:28:41.237742Z",
"deleted": false
I have such a serializer:
...
class SubscriptionsSerializer(serializers.ModelSerializer):
subs_list = SubsListSerializer(read_only=True)
subscriber = SubscribersSerializer(read_only=True)
class Meta:
model = Subscriptions
fields = '__all__'
When get requests everything is ok, but how to update and add data is not clear, error:
IntegrityError at /subscriptions/subscriptions/
null value in column "subs_list_id" violates not-null constraint
DETAIL: Failing row contains (41, 2018-03-01 16:10:02.383625+00, f, null, null).
I struggle with this problem for a very long time, read all the related answers, but there is no clarity.
remove read_only=True and change your serializer.py as below
class SubscriptionsSerializer(serializers.ModelSerializer):
subs_list = SubsListSerializer()
subscriber = SubscribersSerializer()
class Meta:
model = Subscriptions
fields = '__all__'
def create(self, validated_data):
sub_lst = SubsList.objects.create(**validated_data['subs_list'])
subscriber = Subscribers.objects.create(**validated_data['subscriber'])
return Subscriptions.objects.create(subs_list=sub_lst, subscriber=subscriber, deleted=validated_data['deleted'])
And your creation payload will be like this,
{
"subs_list": {
"uuid": "d183bab7-af26-48f8-9ef5-ea48e09a95a9",
"name": "TEST",
"description": "TEST",
# etc etc
},
"subscriber": {
"bot_id": "1",
"name_messenger": "11",
"username": "1",
# etc etc
},
"deleted": null
}
I think you have several ForeignKey relationships are there, so you have to map those things carefully in create()
Similar way, you can override update() and which can be used while API updation too.
See this official doc for more info

Distinct field Rest Framework Django

I need to make a distinct with a field of my model and not how to make
My model is:
class CheckList(CoreModel):
date = models.DateTimeField(default=datetime.now, blank=True, null=True, verbose_name=_('Date'))
establishment = models.ForeignKey(Establishment, related_name="checklists", on_delete=models.CASCADE, null=True, verbose_name=_('Establishment'))
user = models.ForeignKey(ITManager, related_name="checklists", on_delete=models.CASCADE, null=True, verbose_name=_('User'))
class Meta:
verbose_name_plural = _("Checklist")
verbose_name = _("Checklists")
def __str__(self):
return str(self.date)
My serializer and view:
class CheckListSerializer(BulkSerializerMixin, serializers.ModelSerializer):
user = ITManagerSerializer()
class Meta:
model = CheckList
list_serializer_class = BulkListSerializer
fields = ['id', 'user', 'establishment', 'date']
class ChecklistBulkViewSet(BulkModelViewSet):
queryset = CheckList.objects.values('establishment', 'user', 'date').distinct()
model = CheckList
serializer_class = CheckListSerializer
filter_class = ChecklistFilter
The api return me:
"results": [
{
"id": 1,
"user": {
"id": 3,
"first_name": "Andres",
"last_name": "Gallardo",
"rut": "21312",
"email": null,
"user_name": "andres",
"password": null,
"user": 4,
"country": [],
"active": true
},
"establishment": 3,
"date": "2016-06-14T15:15:00Z"
},
{
"id": 2,
"user": {
"id": 2,
"first_name": "Ramiro",
"last_name": "Gutierrez",
"rut": "15616+",
"email": null,
"user_name": null,
"password": null,
"user": 2,
"country": [
{
"id": 1,
"name": "Argentina",
"code_area": null
}
],
"active": false
},
"establishment": 3,
"date": "2016-06-09T15:40:04Z"
}]
I need you just leave me an establishment with the same id
any suggestions??
Thanks !