I’m building a Content Management System which is nearing completion of version 1.
Now that I start building the front-end, which only uses display views, I wonder whether it is possible to have 2 projects in the same virtual environment.
In the future I only want the CMS to be built in Django not the entire project. Furthermore the CMS and front-end will be referenced by different domain names.
However, when it’s done, the venv is usually outside the project directory. (That’s how we deploy all our projects. We never have the venv inside the project - it’s actually easier for us the way we do our deployments.)
I renamed the outer config directory cms and created another project called config and renamed the outer directory frontend. So project is just a name for the directory containing the venv and both projects.
When I run:
(venv) me@my-Mac-mini project % cd frontend
(venv) me@my-Mac-mini frontend % python3 manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 4 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
September 27, 2022 - 14:06:31
Django version 4.1, using settings 'config.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
There’s an issue with migrations, I guess I need to change some settings in the frontend project.
I’m relatively new to Django, but from what I can judge at the moment both apps only have the models and configuration in common. Wouldn’t it be easier to have a project containing the models.py files for every app in a project and have the cms and frontend import the from this project.
Generally speaking, two different projects are each going to be using their own databases. If you’ve got two “projects” that are going to share a database, then they would more appropriately be created as Django apps within the same project.
At most, if you really want them as separate projects, what I recommend is that the data to be shared between the projects be stored in a secondary database to be accessed as such by both projects - allowing each project to maintain its independence of its own default database.
(Trying to have two different Django projects share the same database creates a huge boat-load of issues that need to be managed carefully. It’s not something I recommend unless you’re very aware of those issues and your options for managing them.)
At the moment I’ve got one PostgreSQL database, and before considering multiple databases, I first want to build the CMS and frontend in Django. So, 1 project it is then.
What if I create 1 app for the frontend and create a views folder containing a view.py for every app in the CMS:
It can be made to work, but it will add some work when writing code to ensure the imports are retrieving the right objects.
I do generally recommend the standard project layout
e.g.
project/
app1/
app2/
app3/
project/ # I know a lot of people like to rename this - they're not fond of the duplicated directory names. I have no problem with changing the name, we just don't bother doing it
static/
templates/
where each appx directory contains the models.py, views.py, urls.py, templates, static, management, migrations, etc for that application. We’ve never seen the need to seriously investigate any other pattern for organizing code.
I do have your standard project layout, the only difference being that, based on the books by William Vincent, I named my project `config’ and I renamed the outer directory.
Am I right to conclude that you have both the display views and the editing views for an app in one app, intertwining front-end and back-end?
Would having a views directory in each app with separate views solve this?
I’m not sure by what you mean between “front-end” and “back-end” here, but I’m going to answer that with a qualified “yes”.
A view is a view - it receives requests and returns responses. It’s the interface between the system and the outside world. From my perspective, all views are, by definition, the “front end” of the system. It’s how “anything that isn’t Django” communicates with Django.
And an app is an app. It’s the complete set of code for a specific “module” of functionality.
For example, consider a timesheet application where an individual enters the time spent on each project each day. That app is responsible for everything associated with the entry of timesheet data.
Yes, it uses data provided by other apps. (For example, it’s a different application that identifies which users can work on which tasks.) But all data entered or updated related to a timesheet is done in this app. That means the app contains all views, models, templates, static files, url definitions, etc necessary to allow for someone to enter a timesheet - with the stated assumption that the other required data (task assignment) is available.
We could take that entire timesheet app and install it in a different application, ensure the other application provides the appropriate task assignment model, and use it directly.
I know that large view and model files can be considered unwieldy, but large is a matter of perspective here. We don’t start to consider a file large until it’s more than about 2500 lines.
I think I slowly start getting my head around the way things are done in Django.
To me the back-end is the app where you have to be logged in to create, update and delete database records. The front-end is the app which only retrieves records from the database.
In analogy to your timesheet example, I have an events app where users enter and update event data (sort of a CMS).
I want to use the event data to display event lists for individual users and groups of users on a web site. Following the timesheet example this should be done in the same view as where the user enters and updates data. Did I understand this correctly?
I don’t see an issue with using that as a “mental model” for how your system is organized. However, Django doesn’t provide any features to facilitate implementing that as a physical structure of your code. By default, Django (or perhaps more fundamentally, Python) implicitly encourages you to have all your views in the same file.
I believe you understand this, except that I would have phrased it that all of “these views would reside in the same views.py file”, not that they’re “done in the same view”. (I tend toward being rather pedantic about such things.)
URLs are mapped to views, not to files. What file a view may reside in has no effect on how those URLs reference them other than the imports used to locate those views.
What mechanism makes a request for www.example.com/singleevent respond with the display view named single-event-list and my.example.com/singleevent/editlist respond with the editing view named single-event-edit-list.
A request for .../singleevent does not resolve to the view named single-event-list.
Looking at a couple of your url definitions: path('singleevent/', views.SingleEventListView.as_view(), name='single-event-list'), path('singleevent/editlist', views.SingleEventEditListView.as_view(), name='single-event-edit-list'),
When a request is received, Django gets the url path being requested. It searches through this list to find the first entry that matches the pattern defined as the first parameter (e.g. 'singleevent'). If the pattern matches, then the view identified as a the second parameter is called. (e.g. views.SingleEventListView)
The name of the url single-event-list actually has nothing to do with the request url resolution. It’s functionality is in the other direction. It allows your code internally to refer to a url by name rather than by path. It allows you to change the path when necessary and not have to change the code referring to that view.
To continue with your question then, a request for singleevent/editlist doesn’t match the path singleevent/ so Django would keep looking down the list. The next entry, singleevent/<uuid:pk>/detail also doesn’t match, so Django keeps going. The next entry, singleevent/editlistdoes match, and so Django will call views.SingleEventEditListView.