Django- how to establish relationships between different apps? - django

(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).

Related

Should i use proxy models in django?

im here trying to start a new project, in django
and i came across this problem, while creating the models
My users will be different types of users, so i was thinking, should i use proxy models for it?
because here is how it´s going to be the realtionship between them.
i will have a client, and a personal trainer, and the admin of course, but the problem here is that the client is going to have a ForeignKey with personal trainer, my main question is, can i create in a proxy model an extra field where i establish the relationship with personal trainer proxy model?
If not, is there any other way that i can aproach this type of situation
Thanks in advance
No. As far as I know a Proxy Model only changes the behavior of a model. You can add new methods only. If you want to add new fields it must be a Concrete Model.
You should create a new model class which inherits from AbstractUser. Then you can either add a type field which can be "client" or "personal_trainer" or "whatever". Or you could use a OneToOne field to have a UserProfile associated w/ your user - a different profile for "clients" or "personal_trainers" or "whatevers".

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 write reusable apps with customizable models in Django?

I want to make reusable apps, that allow for customization by the integrator.
An example is if I make a newsletter signup app with the bare minimum of storing email address, but the integrator later wants to add additional fields, like say a name. What is the things I need to do to allow for this easily?
I went down the path of swapping out the models, like Django's auth system does, but that didn't work well. Then I found swappable attribute in the Meta class and a package that does this, but both are not intended for external use.
The only way I can think of for the integrator to do is, allow them to provide custom forms by passing it into the view in the urls for instance.
url('^someurl/$', MyView.as_view(form_class=SomeForm), name="myurl")
Then have a secondary model, with foreign keys to the internal newsletter model, but this means a secondary table that needs to be joined.
Another alternative is to try Abstract models, but I'm not sure what the impact will be there.
So what is the Django/Pythonic way of solving this?

Django models for multiple apps

I am making my way from RoR to Django and am making a a site with two main parts - one with 'User' management and another with 'Resource' management.
As far as I understand, these two will be defined as separate apps (in RoR would have been separate controllers). In Django the default seems to be that each app has a separate model.
How can I use the same model for these two sections? Must I define them as separate apps or can I use the same model for both?
You seem confused.
A model is a class that equates (more or less) to a database table. An app is a collection of models, views and templates. You can have more than one model in an app. If your code is all highly related, then it belongs in one app. If you have more than one area of focus in your code, you should probably have more than one app, although this isn't a requirement.
If you want to use a model from one app in another, just import it.