Let's say i have models like follow.
class Department(models.Model):
name = models.CharField(max_length=255)
class Student(models.Model):
department = models.Foreignkey(Department, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
Now i need to set Department(which is created already) of the Student whenever i create the student instance.
which is best practice
i) Sending the department id in URI like `departments/{pk}/students`
ii) sending department id in body parameter
It is always better to send the sensitive data like ids as Post request instead of passing as URL args. if you really want to pass data in URL then please use slugs instead of ID.
also, you can use DRF model serializer to save the data
in this case, It'd be better to send department id in the body and keep the endpoint simple as
{base}/api/student/
make an HTTP POST to this endpoint
{
"department_id":"",
.
.
}
by taking a look at this endpoint this clearly shows endpoint for operations involving student object, I'd say it's more close to REST standards.
Related
relative to this answer: How to make follower-following system with django model
I will like to know how to get all the post of the user that I'm following just in case I'll want to add that extra functionality in the future.
You will have an another Model Post associated with User.
class Post(models.Model):
description = models.TextField()
user = models.ForeignKey("User", related_name="posts")
Getting all posts of following_user_id, you can achieve by below query
following_user_ids = request.user.followers.all().values_list("following_user_id", flat=True)
posts = Post.objects.filter(user__in=following_user_ids)
request.user is the logged-in user, related_name="followers" is used get all associated records from UserFollowing Model. values_list() will return the following_user_id in list form than pass the returned list in Post
I am working on app where I didnt use serializer in one view I just want to ask am I doing something wrong.
I am getting a committee id in the url and in the body I am getting the usr_id whos status I want to change if someone sends a post request to this end point.
This is my url
path('committee/<int:id>/accept-request/', RequestAcceptView.as_view(), name="accept-request"),
this is my view.py
class RequestAcceptView(APIView):
def post(self, request, id):
user_id = request.data['user']
print("iddddd",user_id )
try :
approve_request = Member.objects.filter(
Q (com=Committee.objects.get(id=id))
).update(mem_status="fully_approved")
return Response(SuccessResponse(msg="Request accepted"))
except:
return Response(ErrorResponse(msg="invalid))
I want to know I am not using serializer here for any purpose, is it fine? should I remove serializer file?
No, it is not when you are using ApiView. Generic and ModelView requires them. You should also think about if you want to have auto generated documentation you need the serializer and it will also perform validation (because you are not using the id field, but request.data.
If request.data and I'd are the same, then you might want to delete the serializer
I am trying to implement a system where a user can subscribe to a company. For that I have to implement the following flow:
User registers
User klicks on a button to subscribe to a company
User has to enter a code (every company has a secret code. By possession the user proves that he is somewhat related to the company)
User is subscribed
For this, I have to implement an API endpoint that receives the code by the user (the user is authenticated at this point).
It is shameful, but I am lost: I am thinking of implementing a view like this.
class RegisterUserToCustomer(APIView):
permission_classes = (permissions.IsAuthenticated,)
def post(self, request, format=None):
serializer = CustomerSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=self.request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.data, status=status.HTTP_400_BAD_REQUEST)
Obviously, I have to:
Receive the code from the user via POST method
Search the database and figure out, if the code corresponds to any company
Edit the ForeignKey field on the user and link it to the company
But where would I implement this logic. With my limited experience I see three possibilities:
Call serializer.save() and write a custom create() method (but I don't want to create anything so this seems like bad practice
Implement this logic in the view, but I want to access the code from the validated_data (this seems like a problem?)
Can I write a custom save() method for the serializer? Are there any examples for a custom save() method since the original drf save() method contains a lot of validation logic.
Obviously I don't expect you guys to write the whole code for me, but maybe someone has somewhat of a blueprint of how and where to implement this?
Steps to do this:
Create a field company_code in Customer table and make that
field as Foreign key.
Create a Serializer with that foreign key field.
Create a viewset or generic views to expect that field from Post method as Id of the Company. Use save() method to store foreign key.
This scenarios is only for Subscribe one organisation, if you're able to subscribe multiple organisation make that field as ManytoMany field.
Refer the code sample,
Models.py
class Customer(models.Model):
# customer related field
name = models.CharField(max_length=20)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
Serializer.py
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('name', 'organization', )
Views.py
class CustomerViewSet(viewsets.ModelViewSet):
serializer_class = CustomerSerializer
queryset = Customer.objects.all()
Request data(POST Json)
{
"name": "test",
"organization": "id-of company"
}
I am developing REST api using Spring Boot. I've a controller which accepts POST requests.
http://localhost:8085/carride/end-ride
In the above request i want to access the parameter ride_transection_id for finding particular transection object and also some other value as well.
So basically i have 3 way to do that.
1. i can use #PathVariable
#RequestMapping(value = "/end-ride", method = RequestMethod.POST)
public ResponseEntity<?> endRide(#PathVariable("ride_transection_id") long ride_transection_id,#RequestBody
SomeDTORequest someDTORequest ) {
//find transaction using path varibale
}
2.i can use #RequestParam
#RequestMapping(value = "/end-ride", method = RequestMethod.POST
public #ResponseBody item getitem(#RequestParam("ride_transection_id")
long ride_transection_id,#RequestBody SomeDTORequest someDTORequest ){
//find transaction using RequestParam varibale
}
i can use DTO Object SomeDTORequest and accept ride_transection_id into that with other value as well.
#RequestMapping(value = "/end-ride", method = RequestMethod.POST)
public ResponseEntity<?> endRide(#RequestBody SomeDTORequest someDTORequest ) {
//find transaction using path someDTORequest .getID()
}
i am little bit confuses.just want ask which is safest and right way to access the ride_transection_id ?
thanks
You can use any of them but every way is designed for a certain use.
Path variable:
is used when you need to access an entity using a certain field for example i want to access an order and this order is defined by id so to access this order i need the following request Get /order/{id}
Request Parameter:
when you want to send a specific variable or flag for a certain method
for example Get /orders?is_shipped=true, so this will get all shipped orders or you may need orders at certain page Get /orders?page=1
Request body:
when you need to update the entity by the put or patch request as you will update the entity using the entity's json representation which can be send through the request body
for example PUT /orders/{id}
body: {"title": "order_1"}
then the order with id {id} will be updated with the new title
Spring data rest
See also
Basically, all these 3 methods are fine. But if you want to develop or design RESTful services with best practices, I strongly recommend you should provide the querying service with #PathVariable and GET method such as GET /tickets/12. Otherwise, to digest request body with #RequestBody annotation to retrieve querying criteria for POST method is the second suggestion.
Because POST method is usually to be used for creating something. And for querying something, both #PathVariable and #RequestParam annotations are suitable for GET method. More specifically, #RequestParam is often to be used in Filtering, Sorting and Searching results. For example:
Filtering: GET /tickets?state=open - Here, state is a query parameter that implements a filter.
Sorting: GET /tickets?sort=-priority,created_at - Retrieves a list of tickets in descending order of priority. Within a specific priority, older tickets are ordered first.
Searching: GET /tickets?state=closed&sort=-updated_at - Retrieve recently closed tickets.
Please also refer to this article Best Practices for Designing a Pragmatic RESTful API.
Hope this helps you! :)
I have three tables: users, emails,attachments. User table is connected with emails by user_id. Emails table is connected with attachments by email_id.
My question is: How should I make it look eloquent in laravel to get all users their emails and their attachments? (I know how get all user and they emails but I don't know how to add attachments.)
Depending on your database relationship,you may declare a relationship method in your Email model, for example:
// One to One (If Email has only one attachment)
public function attachment()
{
return $this->hasOne(Attachment::class);
}
Otherwise:
// One to Many (If Email contains more than one attachment)
public function attachments()
{
return $this->hasMany(Attachment::class);
}
To retrieve the related attachment(s) from Email model when reading a user using id, you may try something like this:
$user = User::with('email.attachment')->find(1); // For One-to-One
$user = User::with('email.attachments')->find(1); // For One-to-Many
Hope you've already declared the relationship method in the User model for Email model using the method name email.
Note: make sure, you have used right namespace for models. It may work if you've done everything right and followed the Laravel convention, otherwise do some research. Also check the documentation.