I'm building a django restful json API using rest_framework libraries, however it returns empty json [ ] when I submit a request to it, even though there's plenty of records in the DB table. Here' my Code
models.py
class Member(models.Model):
email = models.EmailField()
mobile = models.CharField(max_length=11, null=False)
username = models.CharField(max_length=20, null= False, help_text="Username")
password = models.CharField(max_length=15, null=False, help_text="Password")
mobile_id = models.CharField(max_length=100, null=True, blank=True)
joined_date = models.DateTimeField(auto_now_add=True)
serializers.py
class MemberSerializer(serializers.Serializer):
class Meta:
model = Member
fields = ('email', 'mobile', 'username', 'joined_date')
views.py
class MemberAPI(viewsets.ModelViewSet):
serializer_class = MemberSerializer
queryset = Member.objects.all()
urls.py
router = DefaultRouter()
router.register(r'member', MemberAPI, base_name='member')
urlpatterns = router.urls
I got it now. It appears, I was inheriting a base generic class of serialize in
serializers.py
I should have inherited from ModelSerializer like this
class MemberSerializer(serializers.ModelSerializer):
class Meta:
model = Member
fields = ('email', 'mobile', 'username', 'joined_date')
Related
I am creating a custom user class and then I am inheritance this user class to another two classes called Customer and Agent.
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.db.models.deletion import CASCADE
class User(AbstractUser):
username = models.CharField(max_length=50, blank=False, null=False, unique=True)
email = models.EmailField(('email address'), blank=False, null=False, unique=True)
phone_no = models.CharField(max_length=10)
isAgent = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'phone_no']
def __str__(self):
return self.username
class Customer(User):
pass
class Agent(User):
company_name = models.CharField(max_length=150, default="", null=False, blank=False)
company_desc = models.CharField(max_length=1000, default="")
and then i am register this model class in admin pannel like this...
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import Customer, User, Agent, Destination, Trip, Payment
admin.site.register(User, UserAdmin)
#admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['username', 'email']
#admin.register(Agent)
class AgentAdmin(admin.ModelAdmin):
list_display = ['username', 'email', 'company_name']
NOTE : I am also create a model classes like Destination,Trip,Payment just ignore this class...
but in my adminsite http://127.0.0.1:8000/admin/ it is how like this...
https://i.stack.imgur.com/D8sX3.png
==> user class name as "User" , Customer class name as "User" as well as Agent class name as "User"
soo why my orignal model class name is not occure..?
i am new here in django python, I am learning 2 table relations, primary key foreign key scenario, for that i am using existing django user model and create another model userprofile, I want to list data of user and profile, so for that i have created rest api, when i do run api http://127.0.0.1:8000/api/v1/users/, it gives me this error : 'User' object has no attribute 'user'. here i have added my whole code, can anyone please look my code and help me to resolve this issue ?
models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
class Songs(models.Model):
# song title
title = models.CharField(max_length=255, null=False)
# name of artist or group/band
artist = models.CharField(max_length=255, null=False)
def __str__(self):
return "{} - {}".format(self.title, self.artist)
class UserProfile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=255, null=False)
dob = models.CharField(max_length=255, null=False)
address = models.CharField(max_length=255, null=False)
country = models.CharField(max_length=255, null=False)
city = models.CharField(max_length=255, null=False)
zip = models.CharField(max_length=255, null=False)
photo = models.CharField(max_length=255, null=False)
def __str__(self):
return "{} - {}".format(self.title, self.dob, self.address, self.country, self.city, self.zip, self.photo,
self.user)
serializers.py
from rest_framework import serializers
from .models import Songs
from .models import UserProfile
from django.contrib.auth.models import User
class SongsSerializer(serializers.ModelSerializer):
class Meta:
model = Songs
fields = ("title", "artist")
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('user', 'title', 'dob', 'address', 'country', 'city', 'zip', 'photo')
class UserSerializer(serializers.ModelSerializer):
user = UserProfileSerializer(required=True)
class Meta:
model = User
fields = ('url', 'email', 'first_name', 'last_name', 'password', 'user')
extra_kwargs = {'password': {'write_only': True}}
views.py
import rest_framework.generics
from rest_framework import generics
from .models import Songs
from .serializers import SongsSerializer
from .serializers import UserSerializer
from django.contrib.auth.models import User
from rest_framework import viewsets
class ListSongsView(generics.ListAPIView):
"""
Provides a get method handler.
"""
queryset = Songs.objects.all()
serializer_class = SongsSerializer
class UserViewSet(viewsets.ModelViewSet): #generics.ListAPIView, generics.RetrieveAPIView
# viewsets.ModelViewSet
queryset = User.objects.all()
#print(queryset.count());
#exit()
serializer_class = UserSerializer
First of all, I think you need to use a OneToOneField for the User - UserProfile relation. Otherwise, one user may have multiple profiles, which is not common practice.
Now regarding the problem, the User model doesn't have a user attribute. You need to use related_name to get access to the reverse related object.
To fix this problem, you can refactor your code to this:
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="user_profile")
class UserSerializer(serializers.ModelSerializer):
user_profile = UserProfileSerializer(required=True) # rename this field
class Meta:
model = User
fields = ('url', 'email', 'first_name', 'last_name', 'password', 'user_profile')
extra_kwargs = {'password': {'write_only': True}}
I want to perform Update and Delete operation in Django rest framework, I did Get and Post operation. I'm new to django, Please help me to do Update and Delete operation.
views.py
class StudentViews(viewsets.ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentSerializer
models.py
class Student(models.Model):
name = models.CharField(max_length=255, blank=True, null=True)
contact_number = models.CharField(max_length=12, blank=True, null=True)
email = models.EmailField(max_length=100, blank=True, null=True)
address = models.CharField(max_length=500, blank=True, null=True)
serializers.py
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = '__all__'
urls.py
router = routers.DefaultRouter()
router.register('api/student', views.StudentViews)
urlpatterns = [
path('', include(router.urls)),
]
You can do those operations(PUT,PATCH and DELETE) in the api/student/1234/ end-point, where the 1234 is the PK of the instance to be deleted or updated.
You can refer more related to the end-point which is created buy the router automatically here, DefaultRouter--[DRF-DOC]
I am building a backend for a web app using django rest framework. I have a profile model that has a user forieingkey referencing a django user. Everything is loading correctly except for one issue which is that the User field is not showing up in the django rest framework backend urls so that I can assign a user to the profile object i want to create... does anyone know why this is happening...
models.py:
class Profile(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE
)
synapse = models.CharField(max_length=25, null=True)
bio = models.TextField(null=True)
profile_pic = models.ImageField(
upload_to='./profile_pics/',
max_length=150
)
facebook = models.URLField(max_length=150)
twitter = models.URLField(max_length=150)
updated = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username + ' profile'
viewset:
from users.models import Profile
from users.api.serializers.ProfileSerializer import ProfileSerializer
from rest_framework import viewsets
class ProfileViewSet(viewsets.ModelViewSet):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
lookup_field = 'user__username'
url:
from users.api.views.ProfileView import ProfileViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'', ProfileViewSet, base_name='profile')
urlpatterns = router.urls
serializer:
from rest_framework import serializers
from users.models import Profile
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = (
'id',
'user',
'synapse',
'bio',
'profile_pic',
'facebook',
'twitter'
)
depth=2
That happens when you set a depth bigger that 0, foreign key fields become not editable (if you send a POST with that field containing some value, DRF viewset would ignore it, and if the field is required, it will raise an exception).
One solution for that is to override to_representation() method of the serializer and set the depth and restore it to zero:
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = (
'id',
'user',
'synapse',
'bio',
'profile_pic',
'facebook',
'twitter'
)
def to_representation(self, instance):
self.Meta.depth = 2
representation = super().to_representation(instance)
self.Meta.depth = 0
return representation
I cant find a way to auto-populate the field owner of my model.I am using the DRF .If i use ForeignKey the user can choose the owner from a drop down box , but there is no point in that.PLZ HELP i cant make it work.The views.py is not include cause i think there is nothing to do with it.
models.py
class Note(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
cr_date = models.DateTimeField(auto_now_add=True)
owner = models.CharField(max_length=100)
# also tried:
# owner = models.ForeignKey(User, related_name='entries')
class Meta:
ordering = ('-cr_date',)
def __unicode__(self):
return self.title
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', "username", 'first_name', 'last_name', )
class NoteSerializer(serializers.ModelSerializer):
owner = request.user.id <--- wrong , but is what a need.
# also tried :
# owner = UserSerializer(required=True)
class Meta:
model = Note
fields = ('title', 'body' )
Django Rest Framework provides a pre_save() method (in generic views & mixins) which you can override.
class NoteSerializer(serializers.ModelSerializer):
owner = serializers.Field(source='owner.username') # Make sure owner is associated with the User model in your models.py
Then something like this in your view class:
def pre_save(self, obj):
obj.owner = self.request.user
REFERENCES
http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions#associating-snippets-with-users
https://github.com/tomchristie/django-rest-framework/issues/409#issuecomment-10428031