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.
Related
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.
(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).
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?
I want to add Django Sessions to my Django Admin, and I am following an SO post about this, but it is unclear where I store this code. Do I put it in an admin.py file? Under what directory?
In short, it doesn't matter. You can put the code into any of your apps' admin.py files. However, in situations like these I tend to use a generic app in my project, usually named something like utils, that exists for the sole purpose of housing code that doesn't belong to one specific app or could be used by multiple apps.
If you want to be more specific, you can create a sessions app in your project specifically devoted to this code and any other code related to session management for your project, or perhaps an existing app that is somewhat related. For example, I put customizations to the User admin in my accounts app that holds the UserProfile model.
So in my Django project I have a few different apps, each with their own Models, Views, Templates, etc. What is a good way (the "Django" way) to have these Apps communicate?
A specific example would be a Meetings App which has a model for Meetings, and I have a Home App in which I want to display top 5 Meetings on the home page.
Should the Home App's View just query the Meetings App's Model?
It feels like that is crossing some line and there might be a more de-coupled way to do things like this in Django.
At some point your apps will have to couple in order to get any work done. You can't get around that.
To achieve decoupling as much as possible,
You need to have a Project specific app, that does all the hooking up things between each other.
Using signals from models to create new models in a decoupled apps helps. But doing too much of this, is foolish.
Should the Home App's View just query the Meetings App's Model?
Yep, that's how it's done. If you really want to decouple things, you could make your Home app use generic foreign keys, and some sort of generic template system, but there's not really a good reason to, unless you have grand plans for your home app being pluggable and working with a bunch of other different Django apps.
Writing tightly coupled Django apps is really easy, and writing decoupled Django apps is really hard. Don't decouple unless you have a reason to, and you'll save yourself a lot of work (and happiness!).
If it were me, I would make a template tag in your meeting app that produces the desired output and include that template tag in the home app's template.
That way you are only coupling them in the View portion of the MVC and makes it easier to maintain if you change your models in the meeting app.
For your specific example, I would use a Django templatetag.
Having a templatetag "display_top_meetings" in your Meetings app, and calling it with {{ display_top_meetings 5 }} from your index template, loading it first.
You can read more about templatetags here:
Django Official documentation about TemplateTags
B-List's article on writting 'better template tags'
I hope this help!
yes. I think thats a design feature. All models share a backend, so you'd have to do extra work to have two models with the same name in different apps.
Projects should not share Models