Coding Standard - eqraRahman22/ElderEase GitHub Wiki

This document outlines the coding standards for Python Django projects to ensure consistency, readability, maintainability, and quality across the codebase.

1. Consistency

  • Follow PEP 8 (Python Enhancement Proposal 8) as the primary style guide unless explicitly overridden in this document.
  • Maintain consistent coding patterns across the project (e.g., similar structure for views, models, and templates).
  • Use tools like flake8, pylint, or black to enforce consistency automatically.

2. Naming Conventions

Variables

  • Use descriptive, lowercase names with underscores for readability (e.g., user_profile, order_total).
  • Avoid single-letter variables except for loop counters (e.g., i, j).
  • Use meaningful names that reflect the variable's purpose (e.g., is_active instead of flag).

Constants

  • Use uppercase with underscores for constants (e.g., MAX_RETRIES, DEFAULT_TIMEOUT).
  • Define constants at the module level or in a dedicated constants.py file.

Functions

  • Use lowercase with underscores for function names (e.g., calculate_total, send_notification).
  • Use verbs to indicate actions (e.g., get_user, update_order).
  • Avoid generic names like process or handle.

Classes

  • Use CamelCase for class names (e.g., UserProfile, OrderManager).
  • Use nouns to describe the entity or purpose of the class.
  • Avoid abbreviations unless widely accepted (e.g., HTTPClient is acceptable).

Packages and Modules

  • Use lowercase, short, and descriptive names for modules (e.g., utils, models, views).
  • Avoid underscores in module names unless necessary for clarity.
  • Use singular names for modules (e.g., user instead of users).
  • Package names should follow the same rules as modules (e.g., core, auth).

Specific Names

  • Use Django-specific conventions:
    • Models: Singular, CamelCase (e.g., User, Order).
    • Views: Descriptive, lowercase with underscores (e.g., user_detail_view, order_create).
    • URLs: Lowercase with hyphens (e.g., user-detail, order-create).
    • Templates: Lowercase with underscores (e.g., user_detail.html, order_form.html).

3. Comments and Documentation

  • Write clear, concise comments to explain why code exists, not what it does (unless the logic is complex).
  • Use docstrings for all modules, classes, and functions following Google Python Style Guide or NumPy format.
    def calculate_total(order_items):
        """Calculate the total price of all items in an order.
        
        Args:
            order_items (list): List of order item objects.
        
        Returns:
            float: Total price of the order.
        """
        total = sum(item.price for item in order_items)
        return total
  • Avoid redundant comments (e.g., # Set x to 0 for x = 0).
  • Document complex algorithms or business logic thoroughly.
  • Use inline comments sparingly and only when they add value.

4. Formatting and Indentation

  • Use 4 spaces for indentation (no tabs).
  • Follow black formatter for consistent code style.
  • Use a maximum line length of 88 characters (per black default) or 79 characters for strict PEP 8 compliance.
  • Break long lines using parentheses or backslashes for readability:
    result = some_function(
        long_argument_name_1,
        long_argument_name_2,
    )
  • Align arguments or dictionary values for clarity when breaking lines:
    config = {
        "key1": "value1",
        "key2": "value2",
    }

5. Error Handling

  • Use specific exceptions instead of bare except:
    try:
        user = User.objects.get(id=user_id)
    except User.DoesNotExist:
        logger.error(f"User with ID {user_id} not found")
        raise UserNotFoundError
  • Log errors with meaningful context using the logging module.
  • Avoid swallowing exceptions unless absolutely necessary; always log or re-raise.
  • Use custom exceptions for domain-specific errors (e.g., InvalidOrderError).
  • Handle edge cases explicitly in views and APIs (e.g., 404, 400 responses).

6. Import Formatting

  • Group imports in the following order:
    1. Standard library imports
    2. Third-party imports
    3. Local application imports
    import os
    import sys
    
    from django.http import HttpResponse
    from rest_framework.views import APIView
    
    from myapp.models import User
    from myapp.utils import send_email
  • Use absolute imports over relative imports (e.g., from myapp.models import User instead of from .models import User).
  • Avoid wildcard imports (from module import *).
  • Use isort to automatically sort and format imports.

7. URL Formatting

  • Use lowercase with hyphens for URL patterns (e.g., user-detail, order-create).
  • Use meaningful, resource-based names (e.g., users/ for a list, users/<int:id>/ for a detail).
  • Include version prefixes for APIs (e.g., /api/v1/users/).
  • Use Django’s path() or re_path() for clarity:
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path("users/", views.UserListView.as_view(), name="user-list"),
        path("users/<int:pk>/", views.UserDetailView.as_view(), name="user-detail"),
    ]

8. Template Style

  • Use lowercase with underscores for template names (e.g., user_list.html, order_detail.html).
  • Keep templates simple; avoid complex logic (use template tags or filters instead).
  • Use Django’s built-in template tags and filters where possible.
  • Organize templates in a directory structure mirroring the app:
    myapp/
        templates/
            myapp/
                user_list.html
                user_detail.html
    
  • Use consistent indentation (2 or 4 spaces, matching Python code).
  • Include comments for template blocks or complex logic:
    {% comment %} Display user details {% endcomment %}
    <div class="user-details">
        {{ user.name }}
    </div>

9. Code Readability

  • Write self-explanatory code with meaningful variable and function names.
  • Break complex logic into smaller, reusable functions or methods.
  • Avoid nested code blocks deeper than 3 levels; refactor if necessary.
  • Use list comprehensions and generator expressions for concise, readable code:
    # Good
    squares = [x**2 for x in range(10)]
    
    # Bad
    squares = []
    for x in range(10):
        squares.append(x**2)
  • Use type hints for better readability and IDE support:
    def get_user(user_id: int) -> User:
        return User.objects.get(id=user_id)

10. Code Reusability

  • Write modular code with reusable components (e.g., mixins, utility functions, custom template tags).
  • Use Django’s generic views or class-based views for common patterns.
  • Create utility modules for common tasks (e.g., utils.py for email sending, file handling).
  • Avoid duplicating code; refactor repeated logic into functions or classes.

11. Testing and Quality Assurance

  • Write unit tests for all critical functionality using Django’s TestCase or unittest.
  • Aim for at least 80% code coverage; use coverage.py to measure.
  • Use factories (e.g., factory_boy) for test data creation:
    import factory
    from myapp.models import User
    
    class UserFactory(factory.django.DjangoModelFactory):
        class Meta:
            model = User
        name = factory.Faker("name")
        email = factory.Faker("email")
  • Test views, models, forms, and APIs separately.
  • Use pytest or Django’s test runner for testing.
  • Include integration tests for critical workflows.

12. Security

  • Use Django’s built-in security features (e.g., CSRF protection, XSS escaping).
  • Validate and sanitize all user inputs using Django forms or serializers.
  • Use settings.SECURE_SSL_REDIRECT and SECURE_HSTS_SECONDS for HTTPS.
  • Avoid raw SQL queries; use Django ORM to prevent SQL injection.
  • Store sensitive data (e.g., API keys) in environment variables using python-decouple.
  • Follow OWASP guidelines for secure coding practices.

13. Maximum Line Length and Line Break

  • Limit lines to 88 characters (black default) or 79 characters (PEP 8).
  • Break long lines using parentheses, brackets, or backslashes:
    long_query = (
        Model.objects.filter(field1=value1)
        .exclude(field2=value2)
        .order_by("field3")
    )
  • Avoid breaking lines unnecessarily for short expressions.

14. Whitespace in Expressions and Statements

  • Use single spaces around operators and after commas:
    x = 1 + 2
    my_list = [1, 2, 3]
  • Avoid trailing whitespace; use linters to enforce.
  • Use blank lines sparingly to separate logical sections:
    def process_data(data):
        cleaned_data = clean(data)
        
        result = analyze(cleaned_data)
        return result

15. Access Modifiers

  • Use a single leading underscore for protected attributes or methods (e.g., _protected_method).
  • Use double leading underscores for private attributes or methods (e.g., __private_method), but sparingly.
  • Prefer explicit public methods for APIs and interfaces.
  • Document access levels in docstrings if non-standard:
    class MyClass:
        def _protected_method(self):
            """Protected method for internal use."""
            pass
⚠️ **GitHub.com Fallback** ⚠️