How to lock a transaction in Django? - django

There is a case when request is sent multiple times to the server with same data. I want to insert that data in database using ORM of Django. In that data there is a field say 'field_imp' which can only be unique. Right now it gives me integrity error as both the request are trying to insert together. How do I avoid this condition?
How to send multiple request together?
Using terminator open multiple tabs, write the same curl request and send.
Model in Django:
class MyModel(models.Model)
field_imp = models.TextField(unique=True)
I am using Django rest Framework for the api generation and its serializers for data's validation.

The first Method is to lock table,but it is low efficiency;
The second Method is to add both two code points:
add exist check into the serializer.
add try...catch... for integrity error.

I used get_or_create() intead of serializer.save().

Related

In a Django Rest Framework view, does request.user make a database call or the database call happens before the request reaches the view?

I need to retrieve some information about my users and I am trying to avoid making unnecessary database calls.
The information I need is stored in three models: User, UserProfile and Membership.
Both UserProfile and Membership have a OneToOne relationship with the User model.
I know that I can use select_related() to retrieve related models from the database in a single call. So I could do something like:
User.objects.select_related('userprofile').select_related('membership').get(id=request.user.id)
But that must not be correct, because if I am using some user information to do the query, it means I already retrieved this information in a previous call.
So what would be the best way to get this information minimising database calls? Would it be even possible to get the information from these 3 models in a single call?
DRF performs user related DB query inside authentication class. See source here. So if you need to optimize this query you should implement custom autentication class(see details here), override authenticate_credentials method and use optimized query inside it.

Do I have to use Django Models to use the API?

We are migrating our intranet application and have decided to choose the Django framework. We control all of our database via source control and managed scripts, so we do not use the migrate feature to create tables for us. Views and Tables can change, all business logic is held in the database.
I want to make Django API endpoint which is basically select * from my_table_or_view; and Django can return a JSON response with the column names and values. Some database tables have close to 100 columns each so I don't want to write out each and every field name and type just to return a query. What happens if we add another column to the view - will I have to update it in Django as well? What if I change the column type - will my application fail as well?
The frontend is written in VueJS - it makes a request to the API endpoint and should use the columns selected in the frontend, obviously if I remove a column it will break but I don't want to have to add the column in the django framework even if it is not used.
I've read the raw SQL queries section of the docs but i'm not sure where this applies to. Does this logic sit in the views section?
I've tried directing a URL endpoint in URLS.py to a custom class in views.py but not sure this is correct, does this logic need to be in a serializer?
I'd like the simplest method possible, potentially not using models, just raw SQL is fine.
One option for you is to sync your db to django models every time you change your schema and then use it normally, both ORM and raw SQL queries would be possible.
There's a function called inspectdb that does that natively, here is a reference to it
https://docs.djangoproject.com/en/3.1/ref/django-admin/#inspectdb

I am getting user data which I need to manually validate and then send it to a django model to save in the database after manual validation

i am getting user data from a Django form which i need to validate manually and then save it to django model database, the problem is that validation might take 24-48 hours. How do i hold the data temporarily so that when validated that data can be sent to the database using django models automatically, is there any functionality in django which will allow me to do that, if not how to do it.
I would save in the database but without activating the user, it will prevent creating other users with this email address and other similar problems.

django form fields clean method and security

My web application has a lot of forms. I don't use django form classes, since my forms are somewhat complicated (involve with a lot of javascript), so I write the forms and handle them at server by myself.
My question is about "cleaning" the fields data.
I know django forms has a clean() method which supposed to sanitize the data.
But isn't django built-in ORM already clean the data from SQL injection type attacks?
If I have similar code:
field = request.POST['field']
record = SomeModel.objects.get(pk=record_id)
record.field = field
record.save()
I POSTed a < script> tag with some javascript to my server, and I couldn't find any security hole here, since django sanitize the data that is printed in the template.
so what the clean() method adds here exactly, and does this code has any security problems?
The clean() method mainly validates the form data i.e. it verifies if the data inserted in the form fields fits the type of the field and respects some patterns. The SQL injection protection is build into ORM. So if you use django ORM querysets you should be protected from SQL injection attacks. As per docs:
By using Django’s querysets, the resulting SQL will be properly
escaped by the underlying database driver.
Only if you want to run raw SQL or custom SQL queries you have to properly escape any parameters that the user can control.

How to make Tastypie reject unrecognized input data

I am currently using Tastypie to provide a programmatic interface to my Django database. On problem that I've run into a couple of times is that when client code uploads data for a field that doesn't exist, Tastypie ignores it. This means that the client code has no idea that some of the data that it tried to upload was ignored. I'd like to tell the client that it tried to upload an unknown field, possible with a status code 406 (not acceptable).
I have two related questions:
Is it appropriate for RESTful design to reject this extra data?
If so, is there a tidy way to do this through Tastypie?
As an example of my concern, consider this toy Tastypie API:
from tastypie import resources, fields
class DemoResource(resources.ModelResource):
name = fields.CharField()
optional = fields.CharField(blank=True)
If client code uploaded the json data: {name: "new data", optioanl: "this field is misspelled"}, the misspelled optional field would be ignored. My current plan is to use a Tastypie validator to compare the bundle data against the bundle object, but this seems really non-DRY.