Django: Last modified by and created by user automatic saving - django

The age-old question: How can I automatically save last_modifed_user in django models?
I found in several places this general process how to do it using thread local. I'm hesitant to simply implement it that way because I'm not entirely sure of the consequences it has and because all these posts are old.
Is using thread local still the "recommended" way of doing this in django 3? Or does django3 have a better options of doing it?

No, this hasn't changed. Simply because separation of concern is an architectural principle of MVC (model-view-controller), which is also how Django (model-view-template) and most web frameworks with ORM are architected. Models know nothing about the request, it's not available (and in many cases there isn't a request at all when a model is saved, think of management commands or regular tasks running in the background).
The alternative to thread local is to make sure you implement it yourself in the controller layer (view layer in Django):
Create a view mixin that you can mix with all the generic views that use the ModelFormMixin to save the user into the model (ModelFormMixin.form_valid()). Or combine it with a form mixin where the user is passed to the form (FormMixin.get_form_kwargs()) and saved when the form is saved (ModelForm.save()).
Create a ModelAdmin mixin that does the same when saving a model in the django admin site.
This of course means someone on your team may forget to do it when creating new views and forms. The link you posted contains an answer as to the advantages and disadvantages of using thread local.

Related

Why use signals in Django?

I have read lots of documentation and articles about using signals in Django, but I cannot understand the concept.
What is the purpose of using signals in Django?
How does it work?
Please explain the concept of signals and how to use it in Django code.
The Django Signals is a strategy to allow decoupled applications to get notified when certain events occur. Let’s say you want to invalidate a cached page everytime a given model instance is updated, but there are several places in your code base that this model can be updated. You can do that using signals, hooking some pieces of code to be executed everytime this specific model’s save method is trigged.
Another common use case is when you have extended the Custom Django User by using the Profile strategy through a one-to-one relationship. What we usually do is use a “signal dispatcher” to listen for the User’s post_save event to also update the Profile instance as well.

How to dynamically swap default database on the model manager in django?

I am creating a project in django and django rest framework. Its an api for an angular app. The database setup consists of multiple databases. one is default database, all the django tables reside in this database; rest of the databases belong to a type of a user, each user is supposed to have a separate database. So, all the user related data goes to its separate database. To implement the selecting database dynamically, user object has an extra field to store the database to write to.
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
"""Custom User model."""
database= models.CharField(max_length=9)
Reason for doing this was performance improvement as each database is separate, ListView and DetailView would work faster than if the data was stored in the one database only.
I know I can choose a database to store by using the using method on the model manager. In the rest api things work fine and data is being stored in their separate databases, but I end up overriding methods that django has defined. Its adding development cost to the project. Foreign keys and ManytoMany keys needs to be resolved with the current database of the user, which is not happening as I have customized the database setup. Also, my code cant be as good as theirs :p , as they have written django over the course of many years.
I have overwritten many querysets already, but django still uses default database many times. If only I could use the request object in the model manager of django models to swap the default database on per request basis, things would be different i think.
My questions are -
Is there a way to access the request object in the model manager? I could do something to the effect of below code.
class CustomManager(models.Manager):
def get_queryset(self, request):
return super(CustomManager, self).using(request.user.database).get_queryset()
Model manager has _db property that could be used to select database. Would overriding it is advised? if yes, how and where in the code?
Is there a better way to implement the separate databases?
Thanks in advance.
Regards
Using a database router is recommended in Django docs, but the problem is it only accesses the model class.
Found a couple of questions related to the problem of switching databases dynamically. This post has a solution that would solve the problem of passing the request.user or any other parameter by using a threading.local instance.
Someone created a reusable plugin even for this - https://github.com/ambitioninc/django-dynamic-db-router
Hope that helps.

Django- how to establish relationships between different apps?

(Keep in mind that still a begginer to Django) I've been creating my first Django App for a while now. In it, I have a model that represents a geographical area. This means that each instance of that model has the purpose of representing a different area on the map. This app is OK.
I've added a 2nd app, a reusable app, to my project, called django-forms-builder, that can be found here:
https://github.com/stephenmcd/django-forms-builder
This app allows me to create custom forms, in the Django Admin, that work fine. But they are 'stand-alone'/'separated' from anything from my own app.
I would like to establish some connection, from these forms from the 2nd app, to the area model from my own app, so that, as a result, specific forms can be associated to specific areas on the map.
This is really confusing to me, as I've only ever used a single app. I've read the models.py file in the 'django-forms-builder' app, and they are abstract, so it seems establishing foreign key relationships between models is not doable here, therefore I feel completely lost with no clues to follow on.
So my question is how to establish a relationship between different Django apps? I feel like there might be a Django concept, some idea other than model foreign keys that I could learn to accomplish this, and that I simply don't know about.
You have non-abstract models there.
With those you should be able to bind a form to a specific 'location':
from forms_builder.forms.models import Form
class Location(models.Model):
...
form = models.ForeignKey(Form, related_name='locations')
This way you can create and relate a form to multiple locations (I guess/hope that's what you are after).

Django app has multiple database and multiple user

I have written one Django cloud based app. This app will have multiple user and for them multiple database, so that their data should be separate and they can save only to same database.
1) How can we implement it
2) How to automatically one user from login page to assign the database to write on it.
I don't have a complete answer, since you do not give a lot of detail. But here are a couple ots that f hinDjango supports custom database router implementations. A database router is a class that helps django decide which database to use for a particular model. Unfortunately I don't think this mechanism is granular enough for your needs. You can also specify the database to use in your code by using using(name) queryset method and save(using=name) form of save() method for instances. Of course this also means that some features of Django are going to be unvailable to you, since you cannot always expect to have a user. Look at the docs here for more info
https://docs.djangoproject.com/en/dev/topics/db/multi-db/

DjangoRestFramework HTML views timeout

I have created an application that uses django-rest-framework. The problem is that in production with lots of data, the rendering of HTML pages will timeout. This is caused, I believe, by the select fields that represent ForeignKey of the model that take too long to render when all the production data is available. What is the most approriate way to prevent this?
As far as I understand, the problem is with the selectbox loaded with tons of items. The solution that is being used in django admins is to use "raw_id_fields" for the choicefields (or foreign keys) that have lots of items.
Unfortunately, DRF doesn't support Raw ID fields for now. However, you can implement a similar approach by using autocomplete fields. Right now there isn't built-in support, but you can use some external packages as described in DRF's official documentation: http://www.django-rest-framework.org/topics/browsable-api/#autocomplete
You should use select_related()/prefetch_related queryset methods to fetch the associated objects, which fill your selects. Post your models, serializer and a queryset so we can make a real example.