DjangoRestFramework HTML views timeout - django

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.

Related

Django: Last modified by and created by user automatic saving

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.

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.

How to check duplicate posts when submitting a new post in Django admin?

I have coworkers to upload posts through Django admin. The problem is they keep making duplicate posts as we've been covering a lot of posts. Is there a way to find out if a post already exists when typing a certain column or submitting?
I searched about that, but didn't get any useful information.
Your business case seems to be a text that is duplicate if it is case sensitive equal.
On a DB and Django Model level you assure unique entries by adding unique:
class MyModel(Model):
my_field = TextField(unique=True)
To check during input you need JavaScript in the client and an AJAX endpoint on the Django server side. It's actually an Autocomplete/Autosuggest functionality for that field. There are several packages that might help you with that. Out of the box, the Django Admin does not support this.

Django databrowse with custom queryset?

Django's databrowse is very different from the rest of django in that the docs literally don't exist. Has anyone tried to do more that databrowse.site.register on a model? Any code examples?
In particular, I've got a model that has a ForeignKey to an auth.Group and I want databrowse to use this queryset instead of .all():
qs = Model.objects.filter(group__in=request.user.groups.all())
Bonus points for making it possible to have a button that does stuff with the current object (edit/delete/clone/etc). I basically need a simple way to browse and edit rows without giving users access to the admin.
It'd be even better if there was a way to do that on the admin, but I don't want to give users the staff privilege.
There's no way to do this through databrowse. You could try writing a custom Manager for your Model and return the required query set by default.

How can you get future-dated posts in Django?

I just want to do a basic site in Django and the flatpages app is super simple, but it doesn't support a couple of things that I need, namely custom fields and future-dating. That is setting a publish date to some point in the future rather than publishing immediately.
What's the best option for getting future-dated posts in Django?
The answer to this question is the same as your question "Is there anything better than Flatpages?"
django-cms allows you to arrange your flatpages in a hierarchical structure and lets you set a future publish date.
By custom fields I assume you mean fields defined by users? If so then you'll have to implement that yourself on top of django-cms.