Get all data for users Djoser - django

I use userProfile model the following code. It has "OneToOneField" for djoser auth_user. I want gel all data for users.
from django.db import models
from django.contrib.auth.models import User
class userProfile(models.Model):
user=models.OneToOneField(User,on_delete=models.CASCADE,related_name="profile")
date_joined=models.DateTimeField(auto_now_add=True)
updated_on=models.DateTimeField(auto_now=True)
def __str__(self):
return self.user.username
and seralizers class show in bellow;
from rest_framework import serializers
from .models import userProfile
class userProfileSerializer(serializers.ModelSerializer):
user=serializers.StringRelatedField(read_only=True)
class Meta:
model=userProfile
fields='__all__'
I want to get all users using ;
class userAccountsListView(ListAPIView):
queryset=userProfile.objects.all()
serializer_class=userProfileSerializer
It return data like;
[
{
"id": 1,
"date_joined": "2020-04-16T16:50:38.218964+03:00",
"updated_on": "2020-04-16T16:50:38.218996+03:00",
"user": 5
},
{
"id": 2,
"date_joined": "2020-04-30T13:53:48.859116+03:00",
"updated_on": "2020-04-30T13:53:48.859149+03:00",
"user": 6
}
]
I want to get all users info;
[
{
"id": 1,
"date_joined": "2020-04-16T16:50:38.218964+03:00",
"updated_on": "2020-04-16T16:50:38.218996+03:00",
"user": 5,
"first_name": "xxxxx",
"last_name": "xxxxx",
"email":"xxxx",
},
{
"id": 2,
"date_joined": "2020-04-30T13:53:48.859116+03:00",
"updated_on": "2020-04-30T13:53:48.859149+03:00",
"user": 6,
"first_name": "xxxxx",
"last_name": "xxxxx",
"email":"xxxx",
}
]

I added the own CurrentUserSerializer.
class CurrentUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'email', 'id','first_name','last_name')
class userProfileSerializer(serializers.ModelSerializer):
user=CurrentUserSerializer(read_only=True)
class Meta:
model=userProfile
fields='__all__
I get json output;
[
{
"id": 1,
"user": {
"username": "x",
"email": "x",
"id": 5,
"first_name": "x",
"last_name": "x"
},
"date_joined": "2020-04-16T16:50:38.218964+03:00",
"updated_on": "2020-04-16T16:50:38.218996+03:00"
},
{
"id": 2,
"user": {
"username": "x",
"email": "x",
"id": 6,
"first_name": "x",
"last_name": "x"
},
"date_joined": "2020-04-30T13:53:48.859116+03:00",
"updated_on": "2020-04-30T13:53:48.859149+03:00"
}
]

Related

How to change DRF API SlugRelatedField Response template

I have managed to create a working model with 2 different serializers, depending on what we are doing. Right now, ReadTitleSerializer returns the below JSON object:
[
{
"id": 1,
"category": {
"id": 1,
"name": "Movies",
"slug": "movie"
},
"genres": [
{
"id": 1,
"name": "Drama",
"slug": "drama"
}
],
"name": "Drama Llama",
"year": "1998-02-02",
"description": null,
"rating": null
}
]
And this is the response from WriteTitleSerializer:
{
"id": 1,
"category": "movie",
"genres": [
"drama"
],
"name": "Drama Llama",
"year": "1998-02-02",
"description": null,
"rating": null
}
How can I make WriteTitleSerializer respond similarly to ReadTitleSerializer? I am using SlugRelatedField in WriteTitleSerializer because the JSON input should be a list of slugs.
Input JSON
{
"name": "Drama Llama",
"year": "1998-02-02",
"category": "movie",
"genres": [
"drama"
]
}
serializers.py
class ReadTitleSerializer(serializers.ModelSerializer):
category = CategorySerializer()
genres = GenreSerializer(many=True)
class Meta:
model = Title
fields = '__all__'
read_only_fields = ('category', 'genres')
class WriteTitleSerializer(serializers.ModelSerializer):
category = SlugRelatedField(
slug_field='slug',
queryset=Category.objects.all(),
required=True
)
genres = SlugRelatedField(
slug_field='slug',
queryset=Genre.objects.all(),
many=True,
required=True
)
class Meta:
model = Title
fields = '__all__'

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?

Filtering list of elements based on a model #property in a ViewSet - Django Rest Framework

Below is a data structure that can be accessible trough an endpoint built with Django Rest Framework:
"sites": [{
"id": 1,
"configs": [
{
"id": 1,
"subconfigs": [
{
"id": 1,
"name": "subconfig_1",
"macro_subconfigs": [1, 2]
"flag": true
},
{
"id": 2,
"name": "subconfig_2",
"macro_subconfigs": [1]
"flag": false
},
{
"id": 3,
"name": "subconfig_3",
"macro_subconfigs": [2]
"flag": false
},
],
"macro_subconfigs": [
{
"id": 1,
"flag": true,
"subconfigs": [
{
"id": 1,
"name": "subconfig_1",
"macro_subconfigs": [1, 2]
"flag": true
},
{
"id": 2,
"name": "subconfig_2",
"macro_subconfigs": [1]
"flag": false
},
],
"name": "macro_subconfig_1"
},
{
"id": 2,
"flag": false,
"subconfigs": [
{
"id": 1,
"name": "subconfig_1",
"macro_subconfigs": [1, 2]
"flag": true
},
{
"id": 3,
"name": "subconfig_3",
"macro_subconfigs": [2]
"flag": false
},
],
"name": "macro_subconfig_2"
},
]
}
]
}]
My models are the followings:
Config
class Config(TimeStampedModel):
site = models.ForeignKey("site.Site", related_name="configs")
#property
def macro_subconfigs(self):
try:
return MacroSubConfig.objects.filter(subconfigs__config__pk=self.pk).distinct()
except MacroSubConfig.DoesNotExist:
return tuple()
SubConfig
class SubConfig(TimeStampedModel):
name = models.CharField(max_length=200)
config = models.ForeignKey(
"Config", related_name="subconfigs", on_delete=models.CASCADE
)
flag = models.BooleanField(default=True)
MacroSubConfig
class MacroSubConfig(TimeStampedModel):
name = models.CharField(max_length=100)
subconfigs = models.ManyToManyField(SubConfig, related_name="macro_subconfigs")
flag = models.BooleanField(default=True)
And my serializers:
class SiteConfigSerializer(serializers.HyperlinkedModelSerializer):
configs = ConfigSerializer(many=True)
class Meta:
model = Site
fields = ("name", "configs")
class SubConfigSerializer(serializers.ModelSerializer):
class Meta:
model = SubConfig
fields = ("name")
class ConfigSerializer(serializers.ModelSerializer):
subconfigs = SubConfigSerializer(many=True)
macro_subconfigs = MacroSubConfigSerializer(many=True)
class Meta:
model = Config
fields = ("name", "subconfigs", "macro_subconfigs")
class MacroSubConfigSerializer(serializers.HyperlinkedModelSerializer):
subconfigs = serializers.PrimaryKeyRelatedField(
many=True, queryset=SubConfig.objects.all()
)
class Meta:
model = MacroSubConfig
fields = ["subconfigs", "name"]
In my SiteViewSet, I would like to filter macro_subconfigs in the macro_subconfigs's list which have flag: true. I already managed to do the same for subconfigs in the subconfigs's list.
The expected result is the following:
"sites": [{
"id": 1,
"configs": [
{
"id": 1,
"subconfigs": [
{
"id": 1,
"name": "subconfig_1",
"macro_subconfigs": [1, 2]
"flag": true
}
],
"macro_subconfigs": [
{
"id": 1,
"flag": true,
"subconfigs": [
{
"id": 1,
"name": "subconfig_1",
"macro_subconfigs": [1, 2]
"flag": true
},
{
"id": 2,
"name": "subconfig_2",
"macro_subconfigs": [1]
"flag": false
},
],
"name": "macro_subconfig_1"
}
]
}
]
}]
How do you filter elements from a list in the Config object, in the SiteViewSet?
Feel free to ask me more precisions if needed. Thanks
More infos
What I have tried in my ViewSet
class SiteConfigViewSet(PublicViewSet):
serializer_class = serializers.SiteConfigSerializer
def get_queryset(self):
subconfigs = Process.objects.filter(flag=True)
macro_subconfigs = MacroProcess.objects.filter(flag=True)
return permissions.get_allowed_sites(self.request).prefetch_related(
Prefetch("configs__subconfigs", queryset=subconfigs),
Prefetch("configs__subconfigs__macro_subconfigs", queryset=macro_subconfigs),
)

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 !

Django REST Meta data for M2M missing

On my json output I don't seem to get key value pairs on my m2m field attribute_answers. see the code below. How to I add in the attribute_answers fields?
json
{
"id": 20,
"name": "Jake",
"active": true,
"type": {
"id": 1,
"name": "Human",
"active": true,
"created": "2013-02-12T13:31:06Z",
"modified": null
},
"user": "jason",
"attribute_answers": [
1,
2
]
}
Serializer
class ProfileSerializer(serializers.ModelSerializer):
user = serializers.SlugRelatedField(slug_field='username')
attribute_answers = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = Profile
depth = 2
fields = ('id', 'name', 'active', 'type', 'user', 'attribute_answers')
def restore_object(self, attrs, instance=None):
"""
Create or update a new snippet instance.
"""
if instance:
# Update existing instance
instance.name = attrs.get('name', instance.name)
instance.active = attrs.get('active', instance.active)
instance.type = attrs.get('type', instance.type)
instance.attribute_answers = attrs.get('attribute_answers', instance.attribute_answers)
return instance
# Create new instance
return Profile(**attrs)
If I understand your question correctly, you want a Nested Relationship. In your ProfileSerializer, you'll want:
attribute_answers = AttributeAnswerSerializer(many=True)
This will display all the attributes of each associated attribute_answer model and give you something like:
{
"id": 20,
"name": "Jake",
"active": true,
"type": {
"id": 1,
"name": "Human",
"active": true,
"created": "2013-02-12T13:31:06Z",
"modified": null
},
"user": "jason",
"attribute_answers": [
{"id": 1, "foo": "bar"},
{"id": 2, "foo": "bar2"}
]
}