how to make django post accept str rather than pk - reactjs

I have relational DB and a file info to post in it.
DB provides 3 entities holding ForeignKey in some attributes.
Entities are:
File, WorkFile and WorkFileStage
My issue is, when I post info of specific file, I must post on those endpoints, but e.g. WorkFile holds attribute file = ForeignKey(File) - it's an id filed. Which makes me POST all the File data, then GET it for acquring IDs, then POST on WorkFile with those IDs.
THIS IS A LOT OF POSTINGGETINGITERATINGANDPROMISING (as my request are done with axios on react).
What I've tried, is for POST data construct object with just a file=file_name, then search it in the DB on the Django side and serialize.save(). But POST requires pk rather than str for foreignKeys.
With this though process I ended up with:
axios.post().then(axios.get().then(axios.post(then))))
Is there any easy/good practice way of doing it?

Django's POST view can accept whatever you want. As for querying your models via related model properties, check the official documentation: https://docs.djangoproject.com/en/3.1/topics/db/queries/#lookups-that-span-relationships
In your case it should be something like this:
def my_post_view(request, file_name):
try:
work_file = WorkFile.objects.get(file__name=file_name)
except WorkFile.DoesNotExist:
raise Http404
...
where file_name is passed as a part of your endpoint URL.

Related

When updating a model on a RESTful API, should there be an update endpoint per field? or one endpoint for the model?

For a RESTful API, consider a model schema as follows:
MyCoolObject {
field_a
field_b
field_c
}
Is it better to create one update endpoint to update one or many fields on the model (PUT)? Or create one endpoint per field that would only update that one field (PATCH)?
Heuristic: how do you GET the information from your API?
Typically if you get the information a single resource with all of the information included in its representation...
GET /my-cool-object
Then you should also edit that information using the same resource
PUT /my-cool-object
PATCH /my-cool-object
POST /my-cool-object
In cases where you get the information from multiple resources (presumably via links)
GET /my-cool-object
GET /my-cool-object/a
GET /my-cool-object/b
GET /my-cool-object/c
Then you would normally edit the information in its own resource
PUT /my-cool-object/a
PATCH /my-cool-object/a
POST /my-cool-object/a

Django : array within a query string as foo[]=bar1&foo[]=bar2

I need to prepare a Django microservice that offer the following url pattern :
http://<myserver>/getinfo/?foo[]=bar1&foo[]=bar2
it seems to be a very PHP way of doing but i have to mimic it in django ...
Is there a standard way in Django for both designing the URL and retrieving the querystring parameter as a list in the View ?
wrt/ "designing the url", Django's urlpatterns ignore the querystring (they only match on the path), so you don't have anything to do here.
wrt/ retrieving the querystring params as a list, that's already handled by Django's QueryDict:
QueryDict.getlist(key, default=None)
Returns a list of the data with the requested key. Returns an empty list if the key doesn’t exist and a default value wasn’t provided. It’s guaranteed to return a list unless the default value provided isn’t a list.
NB: forgot to add that Django will not automagically remove the brackets from the key so you'll need foos = request.GET.getlist("foo[]") (thanks Daniel Roseman)

How to identify a BackboneJS Model serverside

I'm just getting my head around BackboneJS, but one of the (many) things I'm still struggling with is how exactly the Models Sync up and relate to the serverside DB records.
For example, I have a Model "Dvd", now I change an attribute on the "Dvd" Model, the Name for example, and then I call save(), how exactly does the server side know what DB record to update? Does Backbone hold the DB row ID or something else?
Yes, typically you will set up your Backbone models so that they have database row IDs for any objects you're working with. When one of them is brand new on the client side and not yet saved to the server, it will either have a default or no ID, which doesn't matter since the server will be assigning the ID if and when the initial save transaction succeeds.
Upon saving or updating a model item, Backbone expects the server to reply with some JSON that includes any attributes that have changed since the save or update request was made. In the response to the initial save request, the server informs the client of a newly saved item's row ID (and you can also send along any other information you might need to pass to the client at the same time).
By default, the 'id' attribute of a model object is assumed to be its unique identifier, but backbone lets you change this if you're using a different identifier for the primary key. Just give your model an idAttribute parameter (see the docs for Backbone.Model.extend()) to do that.
Meanwhile, either the urlRoot parameter or a url function can be given to your models to characterize the urls that should be used to send the various ajax requests to the server for a given model.

Should I use Post or Put to edit a person in a database and which should I use to add a new person?

So here is what the method looks like now:
POST person/personId/edit
https://api.example.com/*key*/person/*personId*/edit?FName=Blah
I want this to change the first name of person at personId to Blah.
And if I need to add a person I say:
PUT person/create
https://api.example.com/*key*/person/create
and it will add a person with a new personId.
The general convention is usually:
GET => READ
POST => CREATE
DELETE => DELETE
PUT => UPDATE
A difference I can see is that you are also using different URIs, what is most commonly use is a single resource URI. But, anyways that's debatable so it is a matter of how you like it.
My interpretation of POST and PUT has always been:
POST - The server will receive an entity which it can use to perform an operation or create a resource. If the endpoint's intent is to create a resource, then POST will always create a NEW resource. In any case, each POST will be treated without regards to the state of a resource. You are simply posting information to the server for it to operate on.
Example:
Imagine a web service that will send a message to a user's cellphone. A POST could be used to provide the necessary information to the server which may not be appropriate for a GET. The request payload will include this information. No resources are being created on the server, so the operation returns 200 OK, indicating that the operation was completed successfully. The response may also include a body containing information from the server operation.
Imagine a web service that creates a ticket that is posted on a bulletin board. A POST could contain the information needed to make that post. The information is persisted on the server and returns a 201 Created (and maybe a response body which contains a user id, or a more completed object resulting from the creation). In all cases, when something is POSTed to this endpoint, a NEW ticket is created.
PUT - The server will receive an entity (with an ID, for example) with the intent of creating or replacing a resource. If the resource already exists, it will be replaced with the one within the request, otherwise a new resource will be created. In all cases, something is persisted on the server. Some way to uniquely identify the entity must be provided. In other words, the client is the one that creates the ID because it will be used if entity needs to be created. Most people I know struggle with this reality.
Example:
A web service receives a payload form the client containing user
information. The expectation is that the user will be saved. The
server will check to see if that user exists. If it does, it will
update that user by replacing it (in its entirety) with the new resource provided with
the request and return 200 OK or 204 No Content. If it does not
exist, it will create it and return 201 Created.

Database queries vs quick response

We are making a gamification component for our forum, which is being developed in Django. We would like users to receive badges right away after achieving certain goals. However, we are concerned about the amount of database queries that would be made. For example, take a badge that is given if a post gets a certain amount of views. If the condition for the badge is checked every time the post is viewed, that would be a lot of queries. Is our only other option to check at certain intervals or another event, like the user viewing their profile? That would be less optimal from the user perspective, because of the delay.
There is a different approach that may suit you, using webserver logging and post-processing that log to generate stats. I have used it in Apache with some projects that required pageview hit counts. A similar configuration for other webservers would work the same.
I use django.contrib.contentypes to write down the Content Type ID and Object ID of the object accessed on this example, but you can, of course, log anything you want.
So, in your Apache virtualhost conf file, adding a LogFormat directive like this:
LogFormat "%{X-H-CID}o|%{X-H-OID}o" hitcounter
And then attaching it to a CustomLog:
CustomLog path/to/your/logfile.log hitcounter
This will enable Apache to write down to the logfile the following HTTP headers: X-H-CID and X-H-OID, which represent the ContentType ID and Object ID of the object being hit. From a view, you may add the headers to the HttpResponse:
ctxt = RequestContext(request)
rendered = render_to_string(template, ctxt)
http_res = HttpResponse(rendered)
http_res['X-H-CID'] = content_type_id
http_res['X-H-OID'] = object_id
Replace content_type_id and object_id with your real object props.
This example should write a line like:
16|4353
where 16 is the Content Type ID and 4353 the Object ID. Finally, you can schedule a django custom command to process that logfile and perform the needed actions.

Resources