I am getting error AttributeError: 'Response' object has no attribute 'user' for the below code I have written
I am trying to get the user info from the context and create a notification model. I am getting the above error while returning the statement. I don't understand why I am getting this error
Model
class CourseNotification(models.Model):
uid = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False,
unique=True)
course = models.ForeignKey('Course.Course', on_delete=models.SET_NULL, null=True)
user = models.ManyToManyField('Profile.myUser',null=True)
def get_user(self):
return [i for i in self.user.all()]
def __str__(self):
return self.course.course_title
View
class CourseNotificationView(ModelViewSet):
queryset = CourseNotification.objects.all()
serializer_class = CourseNotificationSerializer
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def get_queryset(self):
if self.request.user.email is not None:
profile = myUser.objects.get(email=self.request.user.email)
if profile is not None:
notification = CourseNotification.objects.filter(user=profile)
return notification
else:
return Response(data={"User": "Unauthorized User"}, status=HTTP_401_UNAUTHORIZED)
def retrieve(self, request, *args, **kwargs):
serializer = self.get_serializer(self.get_queryset(), many=True)
return Response(data=serializer.data)
Serializer
class CourseNotificationSerializer(serializers.ModelSerializer):
class Meta:
model = CourseNotification
fields = '__all__'
def create(self, validated_data):
users = self.context['request'].user
subject = validated_data['course']
if users is None and subject is None or subject == "":
raise serializers.ValidationError({"Invalid": "Subject could not be Invalid"})
checkNotification = self.checkNotification(users, subject)
if checkNotification is not None and checkNotification.status_code == 200:
return checkNotification
validate_subject = self.validateSubject(users, subject)
if validate_subject.status_code == 200:
return validate_subject
get_data = CourseNotification.objects.create(course=subject)
get_data.user.add(users)
get_data.save()
return Response(data=get_data, status=HTTP_201_CREATED, content_type="application/json")
#staticmethod
def checkNotification(users, subject):
get_data = CourseNotification.objects.filter(user=users, course=subject)
if get_data:
for data in get_data:
data.user.remove(users)
data.save()
return Response(data=get_data, status=HTTP_200_OK, content_type="application/json")
#staticmethod
def validateSubject(users, subject):
get_data = CourseNotification.objects.filter(course=subject).exclude(user=users)
if get_data:
subject = CourseNotification.objects.get(course=subject)
subject.user.add(users)
subject.save()
return Response(data=get_data, status=HTTP_200_OK, content_type="application/json")
I am trying to add data to the model through API. I am facing the problem
Related
I am byulding an API using django and DRF my code is this
models.py
class Company(models.Model):
"""Company object."""
name_company = models.CharField(max_length=255)
symbol = models.CharField(max_length=10, unique=True)
cik = models.CharField(max_length=150, blank=True)
sector = models.CharField(max_length=150, blank=True)
industry_category = models.CharField(max_length=150, blank=True)
company_url = models.TextField(blank=True)
description = models.TextField(blank=True)
def __str__(self):
return self.name_company
views.py
class CompanyViewSet(viewsets.ModelViewSet):
"""View for manage company APIs."""
serializer_class = serializers.CompanyDetailSerializer
queryset = Company.objects.all()
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def get_serializer_class(self):
"""Return the serializer class for request."""
if self.action == 'list':
return serializers.CompanySerializer
return self.serializer_class
def perform_create(self, serializer):
"""Create a new Company."""
try:
serializer.save()
except IntegrityError:
print('Symbol exists already.')
pass
serializers.py
class CompanySerializer(serializers.ModelSerializer):
"""Serializer for Company."""
class Meta:
model = Company
fields = [
'id', 'name_company', 'symbol', 'cik', 'sector',
'industry_category', 'company_url',
]
read_only_fields = ['id']
def create(self, validated_data):
try:
instance, created = Company.objects.get_or_create(**validated_data)
if created:
return instance
except IntegrityError:
pass
class CompanyDetailSerializer(CompanySerializer):
"""Serializer for Company details."""
class Meta(CompanySerializer.Meta):
fields = CompanySerializer.Meta.fields + ['description']
And right now i am doing unit tests using in this file.
test_company.py
def create_company(**params):
"""Create and return a sample company."""
defaults = {
'name_company': 'Apple',
'symbol': 'AAPL',
'cik': '0000320193',
'sector': 'Technology',
'industry_category': 'Consumer Electronics',
'company_url': 'https://www.apple.com/',
'description':'',
}
defaults.update(params)
company = Company.objects.create(**defaults)
return company
def test_retrieve_companies(self):
"""Test retrieving a list of Companies."""
create_company()
create_company()
create_company(
name_company='Tesla',
symbol='TSLA',
)
res = self.client.get(COMPANIES_URL)
companies = Company.objects.all().order_by('id')
serializer = CompanySerializer(companies, many=True)
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data, serializer.data)
I am getting IntegrityError, what i want is that the run time continue without stopping execution raising the error that is why i am testing it inserting APPLE twice.
I am trying to catch the error with this code in the views.py but does not catch it.
def perform_create(self, serializer):
"""Create a new Company."""
try:
serializer.save()
except IntegrityError:
print('Symbol exists already.')
pass
my error is this:
django.db.utils.IntegrityError: duplicate key value violates unique constraint "core_company_symbol_50a489f1_uniq"
DETAIL: Key (symbol)=(AAPL) already exists.
Thank you in advance.
I am trying to create chat room instance in database. I need to catch an error when room with two similar users is creating.
Here is my chat-room models.py:
class UserRoom(models.Model):
class Meta:
unique_together = ('user_one', 'user_two')
room_id = models.UUIDField(default=uuid.uuid4, primary_key=True)
user_one = models.ForeignKey('user.User', models.CASCADE, related_name='rooms_one')
user_two = models.ForeignKey('user.User', models.CASCADE, related_name='rooms_two')
def __str__(self):
return f'{self.user_one} | {self.user_two} - {self.room_id}'
serializer.py:
def create(self, validated_data):
user_one = self.context.get('request').user
user_two = validated_data['user_two']
room = UserRoom.objects.create(user_one=user_one, user_two=user_two)
message = ChatMessage.objects.create(
chat_room=room,
sender=user_one,
text=validated_data['message']
)
return room
views.py:
#action(methods=['POST'], detail=False)
def create_chat(self, request):
serializer = CreateChatSerializer(data=request.data,
context=self.get_serializer_context())
serializer.is_valid(raise_exception=True)
a = serializer.save()
return Response(
UserRoomsSerializer(a, context=self.get_serializer_context()).data
)
Also, I need an exception of creating existing room.
you can use .exists() to check if the room exists in the db before calling create
if the room exists you raise a validation exception
for example
serializer.py:
def create(self, validated_data):
user_one = self.context.get('request').user
user_two = validated_data['user_two']
if UserRoom.objects.filter(user_one=user_one, user_two=user_two).exists():
raise serializers.ValidationError("room name is not unique")
room = UserRoom.objects.create(user_one=user_one, user_two=user_two)
message = ChatMessage.objects.create(
chat_room=room,
sender=user_one,
text=validated_data['message']
)
return room
and in your views.py check for validation errors
#action(methods=['POST'], detail=False)
def create_chat(self, request):
serializer = CreateChatSerializer(data=request.data,
context=self.get_serializer_context())
if serializer.is_valid():
a = serializer.save()
return Response(
UserRoomsSerializer(a, context=self.get_serializer_context()).data
)
else:
return Response(serializer.errors)
Good day guy i'm working on an drf api endpoint that requires user uploading image and text to the same endpoint, i've done all that is required but i still keep getting error, below is snippet of my code and error msg
APIVIEW
class CreateProfileView(APIView):
parser_classes = (MultiPartParser,)
serializer_class = schoolProfileSerializer
queryset = schoolProfile.objects.all()
permission_classes = [permissions.AllowAny]
def perform_create(self, serializer):
serializer.save(user=self.request.user)
def post(self, request):
file_upload = schoolProfileSerializer(data =request.data, instance=request.user)
if file_upload.is_valid():
file_upload.save()
return Response(file_upload.data, status=status.HTTP_201_CREATED)
else:
return Response(file_upload.errors, status=status.HTTP_400_BAD_REQUEST )
SERIALIZER
class Base64Imagefield(serializers.ImageField):
def to_internal_value(self, data):
if isinstance(self, six.string_types):
if 'data: ' in data and ';base64, ' in data:
header, data = data.split(';base64,')
try:
decode_file = base64.b64decode(data)
except TypeError:
self.fail('invalide image')
file_name = str(uuid.uuid4())[:16]
file_extension = self.get_file_extension(file_name, decode_file)
complete_file_name = "%s.%s" %(file_name, file_extension)
data = ContentFile(decode_file, name=complete_file_name)
return super(Base64Imagefield, self).to_internal_value(data)
def get_file_extension(self, file_name, decode_file):
extension = imghdr.what(file_name, decode_file)
extension = 'jpg' if extension == 'jpeg' else extension
return extension
class schoolProfileSerializer(serializers.ModelSerializer):
parser_classes = (MultiPartParser, FormParser, )
id = serializers.IntegerField(source='pk', read_only=True)
email = serializers.CharField(source='user.email', read_only=True)
username = serializers.CharField(source='user.username', read_only=True)
badge = Base64Imagefield(max_length=None, use_url=True)
class Meta:
model = schoolProfile
fields = ( 'email', 'id', 'username', 'school_name',
'address', 'badge', 'gender', 'level',
)
def create(self, validated_data, instance=None):
if 'user' in validated_data:
user = validated_data.pop('user')
else:
user = CustomUser.objects.create(**validated_data)
profile, created_profile = schoolProfile.objects.update_or_create(user=user,
**validated_data)
return profile
Angular service
postSchoolProfile(profile: schoolProfile):Observable<schoolProfile>{
const url= `${environment.mainUrl}/school-profile/create`
return this.httpClient.post<schoolProfile>(url, {profile})
}
Error msg
detail "Unsupported media type \"application/json\" in request.
can anyone help out pls ?
class InfoSerializer(serializers.ModelSerializer):
class Meta:
model = EventInfo
fields = ('email', 'pin')
class EventSerializer(DataSerializer, GeoModelAPIView):
# other fields
event_info = InfoSerializer(read_only=True)
def create(self, validated_data):
event_info = validated_data.pop('event_info', {})
event = super().create(validated_data)
EventInfo.objects.create(event=event, **event_info)
return event
Model
class EventInfo(models.Model):
pin = models.CharField(max_length=60, null=False, blank=False)
email = models.EmailField()
event = models.ForeignKey(Event)
POST
{
# other data
"event_info": {
"email": "example#example.com",
"pin": "1234567890"
}
}
So I have a model that is not visible on the browsable API, but I want to be able to save data from POST request to that model. Using this code I can create the objects and it correctly links the info to a correct Event model. However the email and pin fields won't get saved. What I have figured out is that the 'event_info' data from the POST is not visible on the validated_data.
The validation goes to the DataSerializer's validation method but I guess that I should somehow bypass the validation for just the 'event_info' data?
Edit:
class EventViewSet(BulkModelViewSet, JSONAPIViewSet):
queryset = Event.objects.filter(deleted=False)
queryset = queryset.select_related('location')
queryset = queryset.prefetch_related(list of related fields)
serializer_class = EventSerializer
filter_backends = (EventOrderingFilter, filters.DjangoFilterBackend)
filter_class = EventFilter
ordering_fields = (fields to order by)
ordering = ('-last_modified_time',)
def __init__(self, **kwargs):
super().__init__(**kwargs)
def initial(self, request, *args, **kwargs):
super().initial(request, *args, **kwargs)
def get_serializer_context(self):
context = super(EventViewSet, self).get_serializer_context()
context.setdefault('skip_fields', set()).update(set([
'headline',
'secondary_headline']))
return context
#atomic
def create(self, request, *args, **kwargs):
return super().create(request, *args, **kwargs)
def perform_create(self, serializer):
if isinstance(serializer.validated_data, list):
event_data_list = serializer.validated_data
else:
event_data_list = [serializer.validated_data]
super().perform_create(serializer)
My POST request to url http://127.0.0.1:8000/airlines/ fails
Here are models and corresponding serializers in my project. Initially I want to create Airlines information and then add flights later
Can someone please let me know where am I going wrong
models.py
class AirlineFirm(models.Model):
operator_name = models.CharField(max_length=30)
def __unicode__(self):
return "%s" % (self.operator_name)
class Flight(models.Model):
flight_num = models.CharField(max_length=7, primary_key=True)
src = models.CharField(max_length=20)
dest = models.CharField(max_length=20)
outbound_time = models.DateTimeField()
inbound_time = models.DateTimeField()
num_of_seats = models.IntegerField()
ticketPrice = models.FloatField()
delayed = models.BooleanField()
airlinefirm = models.ForeignKey(AirlineFirm)
serializers.py
class FlightSerializer(serializers.Serializer):
flight_num = serializers.CharField(read_only=True)
src = serializers.CharField()
dest = serializers.CharField()
outbound_time = serializers.DateTimeField()
inbound_time = serializers.DateTimeField()
num_of_seats = serializers.IntegerField()
ticketPrice = serializers.FloatField()
delayed = serializers.BooleanField()
airlinefirm = serializers.RelatedField(read_only='True')
#passengers = models.ManyToManyField(Passenger)
def create(self, validated_data):
return Flight.objects.create(**validated_data)
def update(self, instance, validated_data):
pass
class AirlineSerializer(serializers.ModelSerializer):
flights = FlightSerializer(many=True)
class Meta:
model = AirlineFirm
fields = ('operator_name','flights')
def create(self, validated_data):
flights_data = validated_data.pop('flights')
airlinefirm = AirlineFirm.objects.create(**validated_data)
for flight_data in flights_data:
Flight.objects.create(airlinefirm=airlinefirm, **flight_data)
return airlinefirm
views.py
#api_view(['GET','POST'])
def airline(request, format=None):
if request.method == 'GET':
airlines = AirlineFirm.objects.all()
serializer = AirlineSerializer(airlines, many=True)
return Response(serializer.data)
if request.method == 'POST':
#data = JSONParser().parse(request)
serializer = AirlineSerializer(data=request.data)
#import pdb;pdb.set_trace()
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
import pdb;pdb.set_trace()
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
When I send a POST request http://127.0.0.1:8000/airlines/ to my airlines view class I get 404 response
http request
import json
import requests
payload = {'operator_name':'AmericanAirlines','flights':[]}
headers = {'Content-type':'application/json'}
r = requests.post('http://127.0.0.1:8000/',data=json.dumps(payload),headers=headers)
Here is the error message:
AttributeError: Got AttributeError when attempting to get a value for field flights on serializer AirlineSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the AirlineFirm instance.
Original exception text was: 'AirlineFirm' object has no attribute 'flights'.
[18/Feb/2016 13:43:58] "POST /airlines/ HTTP/1.1" 500 112039
You need to and an endpoint to the api in your urls.py if it's not there, then point to it in your request, like:
r = requests.post('http://127.0.0.1:8000/airlines',data=json.dumps(payload),headers=headers)