'Response' object has no attribute 'user' - django

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

how to pass the Integrity error django and DRF without stoping execution raising the error

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.

How to catch an error of creating chat room with two similar users?

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)

how to submit image and text field in single API endpoint using drf and angular

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 ?

Getting and saving value from POST with nested serializer

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)

django rest framework POST request fails with nested serialization

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)