I'm creating an API in Django Rest Framework and i'm thinking about best approach to provide actions like adding a post to user reading list. Firstly i've done it by GET request, because it was looking most natural and url for example looks like /api/posts/{id}/add_to_reading_list/. Now i recognized that GET should be used only to retrieve data so i've changed it to POST method and now url is looking like /api/posts/add_to_reading_list/. The first thing is that i needed to create new serializer specially to handle this action which accepts only id field, because this endpoint should accept only already created posts. Is it how it should be done? I was thinking about sending whole post object in POST method, but doesn't it a waste of bandwidth when i need only id? It will prevent me of creating a new serializer for this specific case, but i don't think that it is a correct approach.
Related
I guys I am very new to Django and app dev and I am having trouble to structure my app.
I am creating an app to send team questionaire.So wokflow is the following:
1) I create a team_project (Team_name)
2) Send Invitations to team members using Emails
3) Based on that invitation Team_member signIn (creating a new user) and are directly assigned to that team created.
I have no idea how to handle that and especially part 3
If you could give me a direction how to do it I will really appreciate
Thx you very much
What you want is a common requirement, so perhaps there is already a library or solution for it.
to write the code from scratch, which is not recommended,
You can define a custom url , like example.com/join_team/some_random_looking_unique_string/
create a model which keeps a random string, email , and maybe some kind of expiration policy. Read the unique string in your view, and retrieve the record associated with it. send a form to get more details like password and etc and save the user in database.
I also found this repo that I think does what you want:
https://github.com/bee-keeper/django-invitations
explain more in your question, and you can get more detailed answers!
For the last few days I’ve been looking into the world of REST frameworks (the Django rest framework in specific).
The concept of a RESTful API seems pretty straight forward but there is one thing I’ve been wondering about.
Let say I have the following data structure:
Group
ID
GroupName
User
ID
UserName
GroupUser
userId
groupId
When working with dependent resources I’ve been wondering how you would return and create these objects.
In the case described above I can think of two ways to create a user and add the user to one or more groups:
Option 1:
I send a POST request with the UserName to the server.
Followed by one or multiple POST request adding the user to one or more groups. Adding non existing groups in separate POST requests.
Or, options 2:
I create the user and add all the groups in the request and let my serialiser take care of any of the groups that have not been created yet.
The second option sounds more efficient but request can probably start looking rather strange since some of the groups will be defined by an ID (know groups) and some by a name (non-existing groups). The main thing with this solution is that the serialisers will be rather different from the models.
My question basically boils down to the following:
In a RESTful API how should you deal with dependent resources?
It becomes pretty obvious if you try naming the things.
Option one would be something like:
// creating the user
POST /user
// adding users to the group
POST /usergroup
POST /usergroup
// adding a new group
POST /group
POST /usergroup
Option two would be more like:
POST /CreateUserAndGroupMappingCreatingMissingGroups
Option two is a RPC model, not a restful model.
REST is about nouns: if you can't name the thing you are posting to, or if that thing looks like a verb, then you haven't built a very restful service.
There is nothing wrong with a RPC service; just be aware of what you are creating.
I get the simple Restful design following one type of object:
GET /users
GET /users/123
POST /users/new
POST /users/1/edit (or PUT)
POST /users/1/delete (or DELETE)
...
Follow a Relationship from a type of object to another:
GET /user/123/company
GET /user/123/roles
POST /user/123/roles/new
…
What about a composite DTO mixing multiple objects in it? For example:
//Listing all users with their companies and primary role
GET /usersWithCompaniesAndPrimaryRoles
//List all companies with users and roles count in each company
GET /companiesWithUsersAndRolesCount
In this case, my API link doesn’t look very clean or Restful to me anymore? I am wondering how I should structure the CRUD of these composite DTOs in a Restful way? Please advise me, or link me to where I can learn how to do that?
Thank you very much.
A Restful design should have such API paths.
Instead, you should use the GET /users URI, and provide query parameters. for example:
GET /users?with_companies=yes
In the Restful, you should not think about URIs as API commands. Try, instead to think about URIs as entities, that you can Get, Insert, change, and delete.
There is no room for other "commands".
That is why, for example,
There shouldn't be POST /users/new API path.
instead, just post to /users.
Another possible RESTfull way is to create a "Query Resource" object using POST, returning "Query Resource ID Number", which will later be used in a separated GET request.
By that you are creating saved queries which can also be efficient for re-querying as well.
hope someone can help me.
I have a stack with Django and tasty pie (I use apikey to authenticate and authorize the users). Let me explain what Im trying to do.
I have several users who can only access their data, so imagine that a user through a rest service access all the rows of the model requestoffer, as follows.
http://127.0.0.1:8001/api/v1/requestoffer/?format=json&username=door1&api_key=84051c6fd1581ad60ffa96bcf5a50d3fc11ccdd3
But I dont want that user access all the requestoffers, I just want him to access the ones he is "proprietary".
Do you have any idea how to do this with either Django or Tastypie?
Did I make myself clear?
If every row belongs to one specific user then you can add it as a foreign key to requestoffer and filter the queryset by the user. Another approach would be to extend Authorization class and implement apply_limits.
class MyAuthorization(DjangoAuthorization):
def apply_limits(self, request, object_list):
if request and hasattr(request, 'user'):
return object_list.filter(requestoffer__user=request.user.id)
return object_list.none()
There are a lot of ways to achieve permission management. Which one suits your needs is totally up to you. One way to achieve this might be to create an 'ownership' relation with the model in question, then create a manager for that model only returning records based on the request. The documentation on model managers is pretty straight forward (and elegant).
To automate the record ownership you could create a CurrentUserField as described in Pro Django, there's also multiple ways to implement that. So a long story short, you should just learn by trial-and-error.
Im using tastypie and i just ran into a problem.
My problem:
Users can post messages and if other users are subscribed to that user they can see those message on their homepage. Its exactly like twitter users tweeting and followers looking at their tweets.
I have a public api for all messages.
I can filter a particular users messages using ?userid=1
Bad solution to problem:
I can filter multiple users messages (and thus solve the problem) using
?userid__in=1&userid__=5&...
But this is not a good way because the url length is going to increase to a possibly unallowed amount. (2000 characters)
Is there a better way of doing this?
Is there a way I can use request.user in a queryset to do a join?
Or should I use some sort of advanced filtering?
Thank YOU!
Tastypie already supports this via __in filtering (everything that ORM supports Tastypie exposes, except negations). No coding is necessary.
Look here: http://django-tastypie.readthedocs.org/en/v0.9.11/resources.html#basic-filtering
path/to/api/resource/?user_id__in=1,2,3,4,5,6
However, you can still have the problem of your URL becoming huge with someone subscribed to many users. What you can do instead is keep this information in the DB model (which user is subscribed to which user as a recursive ManyToMany relationship within the model through a separate joint model).
Then you could expose this through your resource without ever having to specify subscriptions through your URL as a parameter and/or filter. Instead your base queryset in the resource would be:
userids = request.user.subscription_userset.values(id)
provided that you have a self ManyToManyRelationship in your User model. Look here, and here.
What if you had someone pass in a list of user_ids they wanted to see updates for, and then filtered on that? Something like this:
URL: your/api/messages.json?user_ids=5,8,10,25
And then in the code you'd convert that into an actual list, and query:
Message.objects.filter(user__id__in=user_ids)