百度 以《明日之子》《创造101》《吐槽大会》《拜托了冰箱》等为代表的超级综艺矩阵,以及动漫、电影、纪录片、线上音乐等板块都将全力加码,持续构建多元、立体的内容矩阵。
This is a typical starting point for my Django development, with the most common packages I use. Thought I would share this to help others getting started with Junie and Django development. The code examples by Junie are not exactly correct for async development in Django, it uses sync_to_async instead async for to build/get the queryset, so modify it to fit your needs.
Django Project Guidelines
Project Overview
This Django project uses a modern technology stack focused on component-based development and interactive frontend experiences. The project is fully async and follows Django best practices with async class-based views and leverages cutting-edge frontend technologies for high-performance, concurrent request handling.
Technology Stack
Backend
- Django 5.2.4+ - Latest Django framework
- Django-Cotton 2.1.3+ - Component library for frontend components
- Django-HTMX 1.23.2+ - HTMX integration for Django
- Django-Filter 25.1+ - Advanced filtering capabilities
- Django-Extensions - Development utilities
- Django-Environ - Environment variable management
- Django-Allauth 65.10.0+ - Authentication and account management (accounts only, no social auth)
- WhiteNoise 6.9.0+ - Static file serving for production deployments
Frontend
- Tailwind CSS 4.0 - Utility-first CSS framework
- DaisyUI - Component library built on Tailwind CSS
- HTMX - Modern HTML interactions without JavaScript
- Alpine.js - Lightweight JavaScript framework for interactivity
Development Tools
- uv - Fast Python package manager (replaces pip)
- ruff - Fast Python linter, formatter, and import organizer
- npx --watch - CSS compilation and watching
Development Environment Setup
Prerequisites
- Python 3.13+
- Node.js (for Tailwind CSS and frontend tooling)
- uv package manager
Initial Setup
- Clone the repository
- Create virtual environment:
uv venv
- Install dependencies:
uv sync
- Install frontend dependencies:
npm install
- Run migrations:
python app/manage.py migrate
- Create superuser:
python app/manage.py createsuperuser
Running the Development Server
- Start Django server:
python app/manage.py runserver
- Start CSS watcher:
npx tailwindcss -i ./input.css -o ./app/static/css/styles.css --watch
Package Management
Adding Python Dependencies
- Always use
uv add
instead of pip
- For production dependencies:
uv add package-name
- For development dependencies:
uv add --dev package-name
- This automatically updates the
.venv
environment and pyproject.toml
Examples
# Add a production dependency
uv add django-debug-toolbar
# Add a development dependency
uv add --dev pytest-django
# Add with version constraint
uv add "django-rest-framework>=3.14.0"
Project Structure
ajango/
├── .junie/ # Project documentation
│ └── guidelines.md # This file
├── app/ # Django application directory
│ ├── a_project/ # Main project settings
│ ├── core/ # Core application
│ ├── manage.py # Django management script
│ └── db.sqlite3 # SQLite database
├── pyproject.toml # Python dependencies and project config
└── uv.lock # Locked dependency versions
Backend Development Guidelines
Async Class-Based Views
- Always use async class-based views for this fully async Django project
- Inherit from appropriate Django generic views (ListView, DetailView, CreateView, etc.)
- Use async/await patterns for database operations and external API calls
- Use mixins for shared functionality
Example Async Class-Based View
from django.views.generic import ListView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from asgiref.sync import sync_to_async
from .models import MyModel
class MyModelListView(LoginRequiredMixin, ListView):
model = MyModel
template_name = 'core/mymodel_list.html'
context_object_name = 'objects'
paginate_by = 20
async def get_queryset(self):
# Async database query
return await sync_to_async(list)(
MyModel.objects.select_related().all()
)
class MyModelCreateView(LoginRequiredMixin, CreateView):
model = MyModel
template_name = 'core/mymodel_form.html'
fields = ['field1', 'field2']
success_url = reverse_lazy('mymodel-list')
async def form_valid(self, form):
# Async form processing
self.object = await sync_to_async(form.save)()
return await super().form_valid(form)
Django-Cotton Components
- Use Django-Cotton for all reusable frontend components
- Store components in
templates/components/
directory
- Follow component naming conventions
Example Cotton Component
<!-- templates/components/button.html -->
<c-vars primary="False" size="md" />
<button class="btn {{ 'btn-primary' if primary else 'btn-secondary' }} btn-{{ size }}" {{ attrs }}>
{{ slot }}
</button>
HTMX Integration
- Use django-htmx for HTMX-specific functionality
- Leverage HTMX for partial page updates and dynamic content
- Use
hx-*
attributes for interactive elements
Django App Configuration
- Always use full AppConfig paths in
INSTALLED_APPS
instead of just app names
- Use the format
app.[app_name].apps.[AppConfigClass]
for local apps
- This provides better control over app configuration and follows Django best practices
INSTALLED_APPS Organization
- INSTALLED_APPS is organized into three distinct sections for better maintainability and clarity
- This separation makes it easier to manage dependencies and understand the application structure
- The three sections are combined using Python list concatenation
The three sections are:
- CORE_APPS - Django’s built-in applications (admin, auth, contenttypes, etc.)
- THIRD_PARTY_APPS - External packages and libraries (django-cotton, django-htmx, etc.)
- LOCAL_APPS - Project-specific applications using full AppConfig paths
Special Daphne Configuration:
- Daphne is inserted at index 0 when
DEBUG=True
for async development server support
- This ensures daphne takes precedence over Django’s default WSGI server in development
- Daphne provides ASGI support required for this fully async Django project
INSTALLED_APPS Structure Example
# settings.py - Three-section INSTALLED_APPS organization
# Django core apps
CORE_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
# Third party apps
THIRD_PARTY_APPS = [
# Add third party apps here as they are installed
# 'django_cotton',
# 'django_htmx',
# 'django_filters',
]
# Local apps
LOCAL_APPS = [
"core.apps.CoreConfig", # Use full AppConfig path
]
# Combine all apps
INSTALLED_APPS = CORE_APPS + THIRD_PARTY_APPS + LOCAL_APPS
# Add daphne at index 0 if DEBUG is True
if DEBUG:
INSTALLED_APPS.insert(0, "daphne")
Example App Configuration
# settings.py - Correct way to configure apps
LOCAL_APPS = [
"core.apps.CoreConfig", # Use full AppConfig path
"users.apps.UsersConfig",
"blog.apps.BlogConfig",
]
# Avoid using just app names
LOCAL_APPS = [
"core", # Don't do this
"users",
"blog",
]
Custom User Model
- This project uses a custom User model that overrides Django’s default User model
- The custom User model is located in the
core
app and extends AbstractUser
- No additional fields are added - it’s a direct override to allow for future extensibility
- The custom User model is configured via
AUTH_USER_MODEL = "core.User"
in settings.py
Custom User Model Implementation
# app/core/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
"""
Custom User model that extends Django's AbstractUser.
No additional fields are added - this is a direct override of the default User model.
"""
pass
Settings Configuration
# settings.py
# Custom User Model
AUTH_USER_MODEL = "core.User"
Important Notes
- Always create the custom User model before running initial migrations on new projects
- When referencing the User model in other models, use
settings.AUTH_USER_MODEL
or get_user_model()
- The custom User model provides flexibility for future user-related feature additions
Frontend Development Guidelines
Tailwind CSS 4.0
- Use utility classes for styling
- Follow mobile-first responsive design principles
- Leverage Tailwind’s configuration for custom design tokens
- DO NOT modify
styles.css
directly - it’s managed by npx --watch
DaisyUI Components
- Use DaisyUI components as base building blocks
- Customize components using Tailwind utilities
- Follow DaisyUI theming conventions
Example DaisyUI Usage
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">Card Title</h2>
<p>Card content goes here</p>
<div class="card-actions justify-end">
<button class="btn btn-primary">Action</button>
</div>
</div>
</div>
HTMX Guidelines
- Use HTMX for dynamic interactions without full page reloads
- Implement progressive enhancement patterns
- Use appropriate HTTP methods (GET, POST, PUT, DELETE)
Example HTMX Usage
<button hx-post="/api/toggle-favorite/{{ object.id }}/"
hx-target="#favorite-status"
hx-swap="innerHTML"
class="btn btn-ghost">
Toggle Favorite
</button>
Alpine.js Guidelines
- Use Alpine.js for client-side interactivity
- Keep Alpine.js logic simple and declarative
- Use for form validation, modals, and UI state management
Example Alpine.js Usage
<div x-data="{ open: false }">
<button @click="open = !open" class="btn">Toggle Modal</button>
<div x-show="open" class="modal modal-open">
<div class="modal-box">
<h3 class="font-bold text-lg">Modal Title</h3>
<p>Modal content</p>
<div class="modal-action">
<button @click="open = false" class="btn">Close</button>
</div>
</div>
</div>
</div>
File Organization
Templates
Each Django app should have its own templates folder with its own components subfolder for app-specific components:
app/
├── core/
│ └── templates/
│ ├── core/ # App-specific templates
│ │ ├── index.html
│ │ └── detail.html
│ └── components/ # App-specific Cotton components
│ ├── core_button.html
│ └── core_card.html
├── users/
│ └── templates/
│ ├── users/ # App-specific templates
│ │ ├── profile.html
│ │ └── login.html
│ └── components/ # App-specific Cotton components
│ ├── user_avatar.html
│ └── user_form.html
└── templates/ # Global templates (optional)
└── components/ # Global Cotton components
├── base.html # Base template component
├── button.html
├── card.html
└── modal.html
Static Files
static/
├── css/
│ └── styles.css # Generated by Tailwind (DO NOT EDIT)
├── js/
│ └── app.js # Custom JavaScript
└── images/
Development Workflow
Before Starting Development
- Ensure virtual environment is activated
- Run
uv sync
to install/update dependencies
- Start CSS watcher:
npx tailwindcss --watch
- Start Django development server
Adding New Features
- Create/update models if needed
- Create migrations:
python app/manage.py makemigrations
- Run migrations:
python app/manage.py migrate
- Implement class-based views
- Create Cotton components for reusable UI elements
- Style with Tailwind CSS and DaisyUI
- Add HTMX interactions where appropriate
- Test functionality
Code Quality
- Use ruff for linting, formatting, and import management (line length: 120 characters)
- Follow PEP 8 for Python code
- Use meaningful variable and function names
- Write docstrings for complex functions and classes
- Keep templates organized and well-commented
- Use semantic HTML elements
Best Practices
Django
- Use Django-Allauth for authentication and account management (accounts only, no social authentication)
- Implement proper error handling
- Use Django’s form validation
- Follow Django’s security best practices
- Use environment variables for sensitive settings with django-environ
Environment Variables with Django-Environ
- Always use environment variables for sensitive settings (SECRET_KEY, database credentials, API keys)
- Use
.env
file for local development configuration
- Never commit
.env
files to version control
- Use default values for non-sensitive settings
- Organize settings by category (security, database, static files, etc.)
Environment Variable Setup
# settings.py
import environ
# Initialize environment variables
env = environ.Env(
DEBUG=(bool, False),
USE_TZ=(bool, True),
)
# Read .env file
environ.Env.read_env(BASE_DIR.parent / '.env')
# Usage examples
SECRET_KEY = env('SECRET_KEY')
DEBUG = env('DEBUG')
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[])
DATABASE_URL = env.db()
LANGUAGE_CODE = env('LANGUAGE_CODE', default='en-us')
Example .env File
# Security
SECRET_KEY=your-secret-key-here
DEBUG=True
# Hosts
ALLOWED_HOSTS=localhost,127.0.0.1
# Database
DATABASE_URL=sqlite:///db.sqlite3
# Internationalization
LANGUAGE_CODE=en-us
TIME_ZONE=UTC
# Static files
STATIC_URL=static/
STATIC_ROOT=staticfiles/
Django-Allauth Configuration
- Use Django-Allauth for authentication - provides robust account management without social authentication
- Configure allauth for accounts only (no social providers)
- Use allauth’s built-in views and templates for login, signup, password reset, etc.
- Leverage allauth’s email verification and account management features
Django-Allauth Setup
# settings.py - Add to INSTALLED_APPS
THIRD_PARTY_APPS = [
'allauth',
'allauth.account',
# Do not include 'allauth.socialaccount' - we're not using social auth
]
# Allauth configuration
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
# Allauth settings (accounts only)
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_LOGIN_REDIRECT_URL = '/'
ACCOUNT_LOGOUT_REDIRECT_URL = '/'
URL Configuration
# urls.py
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('allauth.urls')), # Allauth URLs
# Your other URLs
]
WhiteNoise Configuration
- Use WhiteNoise for static file serving - provides efficient static file serving for production deployments
- WhiteNoise eliminates the need for a separate web server to serve static files
- Automatically handles static file compression and caching headers
- Works seamlessly with Django’s
collectstatic
command
WhiteNoise Setup
# settings.py - Add WhiteNoise middleware
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # Add WhiteNoise middleware
'django.contrib.sessions.middleware.SessionMiddleware',
# ... other middleware
]
# Static files configuration for production
STATIC_URL = env('STATIC_URL', default='static/')
STATIC_ROOT = env('STATIC_ROOT', default=BASE_DIR / 'staticfiles')
# WhiteNoise settings (optional)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Production Deployment with WhiteNoise
# Collect static files for production
python app/manage.py collectstatic --noinput
# WhiteNoise will automatically serve these files in production
# No additional web server configuration needed for static files
Frontend
- Progressive enhancement approach
- Accessible HTML markup
- Responsive design patterns
- Optimize for performance
- Test across different browsers and devices
Performance
- Use Django’s caching framework when appropriate
- Optimize database queries (use select_related, prefetch_related)
- Minimize HTTP requests
- Use Django’s static file handling efficiently
Common Patterns
HTMX + Django Async Pattern
# views.py
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import get_object_or_404, render, redirect
from asgiref.sync import sync_to_async
class ToggleFavoriteView(LoginRequiredMixin, View):
async def post(self, request, pk):
obj = await sync_to_async(get_object_or_404)(MyModel, pk=pk)
# Async toggle logic here
if request.htmx:
return await sync_to_async(render)(request, 'partials/favorite_status.html', {'object': obj})
return redirect('detail', pk=pk)
Cotton + Tailwind Pattern
<!-- templates/cotton/alert.html -->
<c-vars type="info" dismissible="False" />
<div class="alert alert-{{ type }} {{ 'alert-dismissible' if dismissible }}" {{ attrs }}>
{{ slot }}
{% if dismissible %}
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">?</button>
{% endif %}
</div>
Troubleshooting
Common Issues
- CSS not updating: Ensure
npx --watch
is running
- HTMX not working: Check for proper CSRF tokens
- Cotton components not found: Verify component path and naming
- uv command not found: Install uv package manager
Debug Mode
- Keep
DEBUG = True
in development
- Use Django Debug Toolbar for development debugging
- Check browser console for JavaScript errors
- Use Django’s logging framework for backend debugging
Resources