Add a Slugfield & Overwrite Save in Django Model

To add a SlugField and overwrite the save method in a Django model, follow these steps:

  1. Define the SlugField in the Model: Add a SlugField to your model to store the slug.
  2. Overwrite the Save Method: Customize the save method to automatically generate and assign a slug value before saving the object.

Here’s a step-by-step example:

Step 1: Install Django Extensions (Optional)

If you want to use the slugify function from Django Extensions, install it via pip:

pip install django-extensions

Step 2: Modify Your Model

from django.db import models
from django.utils.text import slugify

class MyModel(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, blank=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            # Generate a unique slug
            self.slug = slugify(self.name)
            # Ensure the slug is unique
            unique_slug = self.slug
            num = 1
            while MyModel.objects.filter(slug=unique_slug).exists():
                unique_slug = f'{self.slug}-{num}'
                num += 1
            self.slug = unique_slug
        super(MyModel, self).save(*args, **kwargs)

    def __str__(self):
        return self.name

Explanation:

  1. SlugField Definition:
    slug = models.SlugField(unique=True, blank=True)
    
    • unique=True ensures that each slug is unique.
    • blank=True allows the field to be empty in the form (the slug will be generated automatically if not provided).
  2. Overwriting the Save Method:
    • The save method is overridden to generate a slug if it doesn’t exist.
    • slugify(self.name) generates a slug from the name field.
    • A while loop ensures the slug is unique by appending a number if a conflict is found.
    • The super(MyModel, self).save(*args, **kwargs) call saves the model instance.

Optional: Using Django Extensions (if installed)

If you installed Django Extensions, you can use its slugify function instead of the one from Django’s utilities:

from django_extensions.db.fields import AutoSlugField

class MyModel(models.Model):
    name = models.CharField(max_length=255)
    slug = AutoSlugField(populate_from='name', unique=True)

    def __str__(self):
        return self.name

This approach simplifies the slug generation and ensures uniqueness using the AutoSlugField.

With these steps, you can add a SlugField and overwrite the save method in your Django model to automatically generate and ensure unique slugs for your model instances.

Query Data in Django Model

Setting Up a Django Model

First, ensure you have a Django model defined. For example, let’s say you have a model called Book:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    isbn = models.CharField(max_length=13, unique=True)

    def __str__(self):
        return self.title

Querying Data

1. Retrieving All Records

To retrieve all records of the Book model:

books = Book.objects.all()

2. Filtering Records

To filter records, you can use the filter method. For example, to get all books by a specific author:

books_by_author = Book.objects.filter(author='John Doe')

You can also chain multiple filters:

recent_books = Book.objects.filter(author='John Doe', published_date__year=2023)

3. Retrieving a Single Record

To retrieve a single record, you can use the get method. This is useful when you are sure the query will return only one result:

book = Book.objects.get(isbn='1234567890123')

Note: get will raise a DoesNotExist exception if no record is found, and a MultipleObjectsReturned exception if more than one record is found.

4. Excluding Records

To exclude certain records, use the exclude method:

non_recent_books = Book.objects.exclude(published_date__year=2023)

5. Ordering Records

To order records, use the order_by method:

ordered_books = Book.objects.order_by('published_date')

To order in descending order:

ordered_books_desc = Book.objects.order_by('-published_date')

6. Limiting Querysets

To limit the number of results returned, you can use Python’s array slicing:

limited_books = Book.objects.all()[:10]

7. Aggregating Data

To perform aggregation, use the aggregate method along with Django’s aggregation functions like Count, Max, Min, Avg, and Sum:

from django.db.models import Avg

average_published_year = Book.objects.aggregate(Avg('published_date__year'))

8. Using Q Objects for Complex Queries

For more complex queries, such as OR conditions, use Q objects:

from django.db.models import Q

books = Book.objects.filter(Q(author='John Doe') | Q(author='Jane Doe'))

9. Raw SQL Queries

If needed, you can execute raw SQL queries:

from django.db import connection

with connection.cursor() as cursor:
    cursor.execute("SELECT * FROM myapp_book WHERE author = %s", ['John Doe'])
    books = cursor.fetchall()

Or use raw manager method:

books = Book.objects.raw('SELECT * FROM myapp_book WHERE author = %s', ['John Doe'])

References
https://docs.djangoproject.com/en/5.0/topics/db/queries/

CRUD Operations in Django Model

In myapp/models.py, define a simple model:

from django.db import models

class Item(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

Run the migrations to create the database schema:

python manage.py makemigrations
python manage.py migrate

In myapp/views.py, create views for handling CRUD operations:

from django.shortcuts import render, get_object_or_404, redirect
from .models import Item
from .forms import ItemForm

def item_list(request):
    items = Item.objects.all()
    return render(request, 'myapp/item_list.html', {'items': items})

def item_detail(request, pk):
    item = get_object_or_404(Item, pk=pk)
    return render(request, 'myapp/item_detail.html', {'item': item})

def item_create(request):
    if request.method == "POST":
        form = ItemForm(request.POST)
        if form.is_valid():
            item = form.save()
            return redirect('item_detail', pk=item.pk)
    else:
        form = ItemForm()
    return render(request, 'myapp/item_form.html', {'form': form})

def item_update(request, pk):
    item = get_object_or_404(Item, pk=pk)
    if request.method == "POST":
        form = ItemForm(request.POST, instance=item)
        if form.is_valid():
            item = form.save()
            return redirect('item_detail', pk=item.pk)
    else:
        form = ItemForm(instance=item)
    return render(request, 'myapp/item_form.html', {'form': form})

def item_delete(request, pk):
    item = get_object_or_404(Item, pk=pk)
    if request.method == "POST":
        item.delete()
        return redirect('item_list')
    return render(request, 'myapp/item_confirm_delete.html', {'item': item})

 

Create a Django Model

Creating a Django model involves defining a class that inherits from models.Model and specifying various fields. Here’s a step-by-step guide to create a Django model with common fields:

  1. Install Django (if you haven’t already):
    pip install django
    
  2. Start a Django Project:
    django-admin startproject myproject
    cd myproject
    
  3. Create an App:
    python manage.py startapp myapp
    
  4. Define the Model: Open the models.py file in your app (myapp/models.py) and define your model. Here’s an example of a Book model:
    from django.db import models
    
    class Book(models.Model):
        title = models.CharField(max_length=200)
        author = models.CharField(max_length=100)
        publication_date = models.DateField()
        isbn = models.CharField(max_length=13, unique=True)
        price = models.DecimalField(max_digits=6, decimal_places=2)
        stock = models.PositiveIntegerField()
        description = models.TextField()
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
    
        def __str__(self):
            return self.title
    
  5. Add the App to Project Settings: Add your app to the INSTALLED_APPS list in the settings.py file of your project (myproject/settings.py):
    INSTALLED_APPS = [
        ...
        'myapp',
        ...
    ]
    
  6. Make Migrations: Create migrations for your model. Migrations are Django’s way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema.
    python manage.py makemigrations myapp
    
  7. Migrate the Database: Apply the migrations to your database.
    python manage.py migrate
    
  8. Register the Model in the Admin Site: To make your model visible on the admin site, you need to register it. Open admin.py in your app (myapp/admin.py) and register your model:
    from django.contrib import admin
    from .models import Book
    
    admin.site.register(Book)
    
  9. Run the Development Server: Start the development server to see your changes.
    from django.contrib import admin
    from .models import Book
    
    admin.site.register(Book)
    
  10. Create a Superuser (if you haven’t already): To access the admin site, you need a superuser. Create one with the following command:
    python manage.py createsuperuser
    

Now, you can log in to the Django admin site at http://127.0.0.1:8000/admin/, add some Book entries, and manage them.

References
https://docs.djangoproject.com/en/5.0/topics/db/models/
https://docs.djangoproject.com/en/5.0/ref/models/fields/

Partial Templates in Django

Creating a Partial Template

  1. Create the Partial Template File: Create a separate HTML file for the partial template. For instance, you might create a file called _header.html for the header of your web pages.
    <!-- templates/partials/_header.html -->
    <header>
        <h1>My Website Header</h1>
        <nav>
            <ul>
                <li><a href="/">Home</a></li>
                <li><a href="/about/">About</a></li>
                <li><a href="/contact/">Contact</a></li>
            </ul>
        </nav>
    </header>
    
  2. Include the Partial Template in Your Main Template: Use the {% include %} template tag to include the partial template in your main templates.
    <!-- templates/base.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My Website</title>
    </head>
    <body>
        {% include "partials/_header.html" %}
        
        <main>
            {% block content %}
            <!-- Main content goes here -->
            {% endblock %}
        </main>
        
        <footer>
            <p>&copy; 2024 My Website</p>
        </footer>
    </body>
    </html>
    
  3. Extending the Base Template: If you are using a base template that other templates will extend, make sure to extend it properly in your child templates.
    <!-- templates/home.html -->
    {% extends "base.html" %}
    
    {% block content %}
    <h2>Welcome to My Website!</h2>
    <p>This is the homepage.</p>
    {% endblock %}

Using Context in Partial Templates

If you need to pass context variables to a partial template, you can include it with additional context using the with keyword.

  1. Update the Partial Template:
    <!-- templates/partials/_header.html -->
    <header>
        <h1>{{ site_name }}</h1>
        <nav>
            <ul>
                <li><a href="/">Home</a></li>
                <li><a href="/about/">About</a></li>
                <li><a href="/contact/">Contact</a></li>
            </ul>
        </nav>
    </header>
    
  2. Include the Partial Template with Context:
    <!-- templates/base.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{{ title }}</title>
    </head>
    <body>
        {% include "partials/_header.html" with site_name="My Awesome Website" %}
        
        <main>
            {% block content %}
            <!-- Main content goes here -->
            {% endblock %}
        </main>
        
        <footer>
            <p>&copy; 2024 My Awesome Website</p>
        </footer>
    </body>
    </html>
    

By breaking your templates into partials and using the {% include %} tag, you can keep your templates clean, modular, and easy to manage. This approach is particularly useful for repetitive components like headers, footers, navigation bars, and sidebars.

Template Inheritance in Django

Basic Concepts

  1. Base Template: A general template that includes common elements (like headers, footers, and navigation bars) used across multiple pages.
  2. Block Tags: Special tags in Django templates that define sections of the template that can be overridden by child templates.

Steps to Implement Template Inheritance

1. Create a Base Template

First, create a base template that includes the common layout for your website. For example, base.html:

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My Site{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/styles.css' %}">
</head>
<body>
    <header>
        <h1>Welcome to My Site</h1>
    </header>

    <nav>
        <ul>
            <li><a href="{% url 'home' %}">Home</a></li>
            <li><a href="{% url 'about' %}">About</a></li>
            <li><a href="{% url 'contact' %}">Contact</a></li>
        </ul>
    </nav>

    <div class="content">
        {% block content %}{% endblock %}
    </div>

    <footer>
        <p>&copy; 2024 My Site</p>
    </footer>
</body>
</html>

2. Create a Child Template

Next, create a child template that extends the base template. For example, home.html:

{% extends 'base.html' %}

{% block title %}Home - My Site{% endblock %}

{% block content %}
    <h2>Home Page</h2>
    <p>Welcome to the home page of my awesome site!</p>
{% endblock %}

3. Render the Template in Views

In your Django views, render the child template. For example, in views.py:

from django.shortcuts import render

def home(request):
    return render(request, 'home.html')

4. URL Configuration

Ensure you have the appropriate URL configuration in urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    # other paths
]

Key Points to Remember

  • {% extends 'base.html' %}: This tag is used in the child template to specify the base template it extends.
  • Block Tags ({% block content %}{% endblock %}): Define sections in the base template that can be overridden by child templates.
  • Static Files: Use the {% static %} template tag to include static files like CSS and JavaScript.

Example Directory Structure

Here’s an example of what your directory structure might look like:

myproject/
    myapp/
        templates/
            base.html
            home.html
        views.py
        urls.py
    myproject/
        settings.py
        urls.py
        wsgi.py

By using template inheritance, you can efficiently manage and update the layout and design of your website while ensuring consistency across different pages.

Vite Server is running but not working on localhost

vite.config.ts

import {defineConfig} from 'vite'
import react from '@vitejs/plugin-react'
import dns from 'node:dns'

dns.setDefaultResultOrder('verbatim')

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [react()],
    server: {
        host: '127.0.0.1'
    }
})

References
https://stackoverflow.com/questions/70694187/vite-server-is-running-but-not-working-on-localhost
https://vitejs.dev/config/server-options.html#server-host