Updating the default startapp template

Hi there,

I was creating a custom startapp template for my project and was looking at the one that ships with django, which has not been modified for 3 years (and most of it is 7 years old).

There are also some curious decisions in this template. For example, it creates a views.py file, but not a urls.py file.

While acknowledging that what exactly belongs in there is likely something that everyone will disagree on, has there ever been any consideration of updating it? And if so, is it clear what the process of getting to consensus on what updates to make would look like?

(I could throw out some opinions on what should be changed, but not sure it’s worth going down that rabbit hole yet until understanding what the process would be of getting the changes made)

Here’s the original ticket requesting this: #25943 (Auto Generated urls.py On startapp) – Django

The same question keeps popping up again since that was raised.

Consensus seems to be to not add it. (It used to be part of it apparently but then was taken out).

Note that you can customise the startapp template with the --template arg: django-admin and manage.py | Django documentation | Django

Hey Cory.

This and startproject too… I’m not sure what the way is. Create yours, do a post, get some feedback, etc.

It’s not just urls.py, templates and static folders: some folks insist on those at project level, others at app level, and so on.

Right, so I think it will be very difficult to get people to agree on what exactly should go in there. And at the same time, I suspect that whatever decisions were made 8 years ago could maybe use an update? How often are people writing apps with views and not adding a urls.py?

I imagine an ideal future state might be some set of officially supported templates that people can pick and choose form. E.g. “bare bones”, “empty files only”, “full-blown-example”, etc. Though probably no one wants to maintain that mess.

If we’re only going to have a single template though, perhaps the tutorial is a reasonable guide on what belongs? I believe that the urls.py file is the only non-template file that is not created by startapp. Based on my observations urls.py is far more commonly used than tests.py (not saying that’s a good thing, just that it’s true). Personally, I’d also want to see a url mapped to a dummy view, just to have that wired up and ready to go. I’d also push tests into a module instead of a single file. You can see what I mean in the template that I’m currently using: GitHub - saaspegasus/app_template

Anyway, this isn’t a “problem” for me, it just feels like a silly small own-goal in terms of shipping something that could be more useful for 90% of the people using it…

3 Likes

I would be happy with adding a minimal urls.py like:

from django.urls import path

# Create your URL patterns here.
urlpatterns = []

I think we could cite past discussions as sufficient consensus. The total on the mailing list discussions seems to be mostly positive, and Cory’s post is a repeat of a request since 17 years ago.

This gets more bikesheddy: class-based or function-based view? what would the URL be, and should it have a parameter? And so on.

I’m more in favour of copying the existing templates: some imports and a comment on what to do next.

Idea: override startapp in SaaS Pegasus projects to default the template option to your custom template.

3 Likes

Thanks, I think that’s a good compromise and agree with your points. I’ll submit a PR later today. And to be clear on my other suggestions I wasn’t implying that my preferred changes were a good idea for everyone, just throwing them out there.

And thanks for the suggestion re: overriding for Pegasus! Have started there and will maybe expand / customize over time. I do still think that having some tooling in place to expand on the single template without having to find and/or roll your own file structure would be nice. Could maybe start it as an installable package + a web app of hosted options. May build this into Pegasus, but will try to make it something that could be shared back to the community… :thinking:

I’m not against this idea but I think the proposed skeleton may be confusing for new users (because of the empty list for urlpatterns).

More so, when startproject is ran, the urls.py has a nice module-level comment block with instructions in how to use/grow that file:

"""
URL configuration for emptytest project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/dev/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path("admin/", admin.site.urls),
]

The proposed per-app urls.py feels like it may need a comment block or reference to the one in the projects’s main urls.py, since it’s very helpful.

Also, I would be of the opinion that the urlpatterns = [] should be removed, so it’s consistent with models.py and views.py (one import line and one comment line and nothing else).

Natalia.

I’m against the idea. An app without urls.py is totally valid, and not so rare.

-1 from me.

What percentage of apps that have a views.py would you guess have a urls.py?

My intuition is that it’s above 90. But even if it’s above 50 the logical choice would be to include both. Why not set things up for the most common case and then have people delete the files they don’t need? Some apps don’t have models. Some apps don’t have tests. The whole thing is arbitrary, but at least having both urls and views together is internally consistent.

Most experienced developers won’t use startapp or they’ll have their own custom startapp. It exists primarily to help beginners. So let’s help them!

1 Like

I’ve been using startapp all my life, without a custom template. I don’t agree that this is a beginners-only tool.

I said “most”, but either way, that’s tangential to the larger point. Do you disagree that more often than not an app with a views file also includes a urls file? Can you please make an argument for why views is included but urls isn’t? Like, is that a common configuration that I’ve just managed to mostly avoid for the 15 years I’ve been using Django?

I agree that having a views.py without urls.py most likely goes against what 95% of the apps are doing.

I’d go a bit further than Adam and suggest a default urls.py along the lines of:

from django.urls import path

from . import views

# Create your URL patterns here.
urlpatterns = []

So essentially preimport the views module for usage.

1 Like

@felixxm As the primary dissenter against a change that many people on this thread seem to agree is sensible, it would be nice to understand your reasoning against the points being made.

I understand your previous objection that “the current setup produces valid apps”. However the point being made is that adding a basic urls.py would continue to produce valid apps, however, these apps would have the added benefit of being more internally consistent with how Django apps are normally structured. I’m unclear whether you disagree with that statement, or have some other reason for your strong objection that I haven’t heard yet.

My vote doesn’t count any more than anyone else. I’m not a blocker, but I have “opinions” and may disagree :smile: You can add as many files as you want to the default app, why not forms.py or utils.py etc. I’m pretty sure that more than 50% of apps have a forms.py :upside_down_face: etc. You can check previous topics, where folks immediately tried to force more files, because “they are always needed”. This is can of worms. As for me, the current shape of the default app is the right consensus. More files can be scary for newcomers, this is something that I could never understand in other languages/framework where launching a new app generates dozens of files, which I was afraid to inspect/remove/edit. My 2¢.

Best,
Mariusz

Thanks @felixxm and apologies if I misunderstood. In other open source communities I’ve been involved in a “-1” from a contributor was equivalent to a veto, and I thought that was true here.

Right, so I agree with this, and I don’t think anyone on this thread is trying to make any of those points. As I already said, I agree that is an opinionated rabbit-hole to go down.

Generally, I get this point. I just don’t think it applies specifically to adding a urls.py file. If you’re using views.py then you very likely want urls.py. So I feel the confusion of one being included and the other not outweighs the potential confusion of the one additional file. If you were making the argument for removing views.py instead, I could see that also as a potential option to address the current inconsistency, but I think it’s more likely that Django app will have views (and urls) and so we should have both.

Given that your -1 is not a veto and everyone else on the thread seems to be aligned on the bones of this small change, what is the further process for getting the PR merged? Apologies, it’s my first contribution and I don’t know how these decisions get moved forwards.

Outside of the very beginnings of a project, startapp is used very infrequently. Saving a few keystrokes every few weeks (or less) is a non-issue.

IMO the only relevant question is “does this makes the framework easier or more difficult to learn for a beginner”. Mariusz brings up the additional cognitive load of having another file. I think this is a fair comment, but I think there is a bit less to understand here as there’s already a urls.py generated when using startproject.

I also think we should be considering some simple best practices for newcomers. I don’t know if I’d call it “best practice” but it’s usually good to have views and their corresponding urls in the same app, as much as possible. I’ve come across plenty of projects from less experienced devs where there are tens of URLs in the main urls.py.

I don’t think either side has enough data to understand which is actually a better experience for beginners, we’re mostly working on feel here, so I’m fairly neutral on this, but if I did have any opinion it’s that I prefer Florian’s approach here as it shows that you generally should be using your urls.py for the views in that same app, which I think is usually a good paradigm to encourage.

I would argue against any other files in here, anyway. I don’t think there’s a slippery slope here. Maybe 50%+ of apps have forms.py but a good chunk don’t, especially those using DRF or other API frameworks.

1 Like

Thanks for the input Tom. I’d be very happy to add the view import (I do that in my own template) if we agree that is better.

But before making that change, can anyone explain to me how the decision to merge the change will work? Obviously there will not be 100% agreement on the details, but I would hope that if all (or perhaps at least a very strong majority) of participants could agree to a simple statement like: “the proposed PR is an improvement on the previous version” then we don’t have to spend a long time debating the details.

I’m happy to set up some votes (e.g. one for urls or no and a second one for views import in the urls or no), but I’m disinclined to spend effort on this if the end result is just going to be indecision or no clear path to getting the changes in.

It wasn’t long after posting this message that someone in the Discord asked why a second urls.py is necessary (they were following a youtube tutorial that used startapp and then created a urls,py. However you can still make an argument either way here. Maybe if the urls.py was created for them they wouldn’t have asked. But I think it’s more likely they still would have been confused. So I think I’m roughly -0 on this but I’m open to being swayed.

@czue with regards to making a decision, this has also been discussed recently on the Discord. I think the process if a consensus can’t be found is to put together a proposal and ask the steering council to vote on it.

I’ll take that as an invitation to sway you. :slight_smile:

First, I tend to agree that if the urls.py had been there in the first place they wouldn’t have asked. I have seen so many tutorials (including Django’s own) which are like "ok run startapp and then add a urls.py file). This to me is a very clear signal that the file should already be there! And I suspect (and obviously we’re all speculating) that at least part of the confusion stems from the fact that the startapp command doesn’t include it.

Second, and I think more importantly, there are two important and sometimes competing goals when helping beginners. The first is reducing confusion, which we all agree is important. And if it were true that including a urls.py file was net-confusion-increasing (which I disagree it is) then that would at least be a good reason to be against it. However, the second goal of helping beginners is teaching them how to be successful in the framework. That is, ramping up on common/best practices, understanding how apps are put together, etc. And towards that second goal I think it is very clearly net positive to teach people that it is a good/common practice to include an app-specific urls.py file when that app has its own views. The built-in tutorial agrees. The django-girls tutorial agrees. The simple is better than complex tutorial agrees. The channels tutorial agrees. The youtube tutorial that you mentioned on Discord agrees. And in fact, I would be impressed if anyone is able to find any recent, highly recommended Django resource that does not add an app-specific urls.py file.

So quite literally everyone is already doing this. But we don’t want to just make it the default because… ?

1 Like

For kicks, I asked GPT-4 this question.

what files are typically included in a django app?

I found its (unmodified) response amusing. Emphasis mine:

A typical Django app directory structure includes the following files:

  • __init__.py: This is an empty file that tells Python that this directory should be considered a Python package.

  • admin.py: This file is used to define the admin interface for your app.

  • apps.py: This file is used for application specific configurations.

  • models.py: This file is used to define the data models of your app.

  • tests.py: This file is used to write tests for your app.

  • views.py: This file is used to handle the request/response logic for your app.

  • migrations/: This directory is used to store migration files which Django uses to create the database schema.

  • templates/: This directory is used to store HTML templates.

  • static/: This directory is used to store static files like CSS, JavaScript, images etc.

  • urls.py: This file is not created by default when you create a new Django app using the startapp command. However, it’s a good practice to create this file for including the URLs of your app. This file is used to define the URL routing for your app.

Here is a sample structure:

myapp/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py
    templates/
    static/
    urls.py

Remember, this is just a typical structure. Depending on the complexity and requirements of your app, you might have more files or directories, such as forms.py (for forms), signals.py (for signals), managers.py (for custom managers), utils/ (a directory for utility functions or classes), and so on.