[go: up one dir, main page]

0% found this document useful (0 votes)
27 views12 pages

Django Basics

Uploaded by

mukesh.khanijo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views12 pages

Django Basics

Uploaded by

mukesh.khanijo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 12

================================================================================

DJANGO BASICS & MVT PATTERN - MID-LEVEL DEVELOPER INTERVIEW QUESTIONS


================================================================================

Q1. DJANGO PROJECT STRUCTURE


----------------------------
Question: Explain the basic Django project structure and the purpose of each
directory/file.

Solution:
```
myproject/
├── manage.py # Django's command-line utility
├── myproject/ # Project configuration directory
│ ├── __init__.py
│ ├── settings.py # Project settings and configuration
│ ├── urls.py # Root URL configuration
│ ├── wsgi.py # WSGI application entry point
│ └── asgi.py # ASGI application entry point
├── myapp/ # Django application
│ ├── __init__.py
│ ├── admin.py # Admin site configuration
│ ├── apps.py # App configuration
│ ├── models.py # Database models
│ ├── views.py # View functions/classes
│ ├── urls.py # App-specific URL patterns
│ ├── tests.py # Test cases
│ └── migrations/ # Database migration files
└── templates/ # HTML templates
└── myapp/
└── index.html
```

Key Points:
- `manage.py`: Django's command-line utility for administrative tasks
- `settings.py`: Contains all project settings (database, installed apps,
middleware, etc.)
- `urls.py`: URL routing configuration
- `models.py`: Database schema definition
- `views.py`: Business logic and request handling
- `templates/`: HTML template files

Q2. CREATING A BASIC DJANGO APP


-------------------------------
Question: Create a simple Django app for a blog with basic models and views.

Solution:
```python
# models.py
from django.db import models
from django.contrib.auth.models import User

class Category(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"

class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
is_published = models.BooleanField(default=False)

def __str__(self):
return self.title

class Meta:
ordering = ['-created_at']

# views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView
from .models import Post, Category

def home(request):
"""Home page view"""
latest_posts = Post.objects.filter(is_published=True)[:5]
categories = Category.objects.all()

context = {
'latest_posts': latest_posts,
'categories': categories,
}
return render(request, 'blog/home.html', context)

class PostListView(ListView):
"""List view for all posts"""
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
paginate_by = 10

def get_queryset(self):
return Post.objects.filter(is_published=True)

class PostDetailView(DetailView):
"""Detail view for individual posts"""
model = Post
template_name = 'blog/post_detail.html'
context_object_name = 'post'

def get_queryset(self):
return Post.objects.filter(is_published=True)

# urls.py
from django.urls import path
from . import views

app_name = 'blog'
urlpatterns = [
path('', views.home, name='home'),
path('posts/', views.PostListView.as_view(), name='post_list'),
path('post/<int:pk>/', views.PostDetailView.as_view(), name='post_detail'),
]
```

Q3. DJANGO TEMPLATES AND TEMPLATE INHERITANCE


---------------------------------------------
Question: Create a base template and extend it for different pages in your blog
app.

Solution:
```html
<!-- 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>{% block title %}My Blog{% endblock %}</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="{% url 'blog:home' %}">My Blog</a>
<div class="navbar-nav">
<a class="nav-link" href="{% url 'blog:home' %}">Home</a>
<a class="nav-link" href="{% url 'blog:post_list' %}">Posts</a>
</div>
</div>
</nav>

<main class="container mt-4">


{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
{{ message }}
</div>
{% endfor %}
{% endif %}

{% block content %}
{% endblock %}
</main>

<footer class="bg-light text-center py-3 mt-5">


<p>&copy; 2024 My Blog. All rights reserved.</p>
</footer>

<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js">
</script>
</body>
</html>
<!-- templates/blog/home.html -->
{% extends 'base.html' %}

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

{% block content %}
<div class="row">
<div class="col-md-8">
<h1>Welcome to My Blog</h1>
<h2>Latest Posts</h2>
{% for post in latest_posts %}
<article class="card mb-3">
<div class="card-body">
<h5 class="card-title">{{ post.title }}</h5>
<p class="card-text">{{ post.content|truncatewords:30 }}</p>
<p class="text-muted">
By {{ post.author.username }} | {{ post.created_at|date:"F
j, Y" }}
{% if post.category %}
| {{ post.category.name }}
{% endif %}
</p>
<a href="{% url 'blog:post_detail' post.pk %}" class="btn btn-
primary">Read More</a>
</div>
</article>
{% empty %}
<p>No posts available.</p>
{% endfor %}
</div>

<div class="col-md-4">
<h3>Categories</h3>
<ul class="list-group">
{% for category in categories %}
<li class="list-group-item">{{ category.name }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}

<!-- templates/blog/post_detail.html -->


{% extends 'base.html' %}

{% block title %}{{ post.title }} - My Blog{% endblock %}

{% block content %}
<article>
<h1>{{ post.title }}</h1>
<p class="text-muted">
By {{ post.author.username }} | {{ post.created_at|date:"F j, Y" }}
{% if post.category %}
| Category: {{ post.category.name }}
{% endif %}
</p>

<div class="content">
{{ post.content|linebreaks }}
</div>

<a href="{% url 'blog:post_list' %}" class="btn btn-secondary">Back to


Posts</a>
</article>
{% endblock %}
```

Q4. DJANGO FORMS


----------------
Question: Create a form for adding new blog posts with validation.

Solution:
```python
# forms.py
from django import forms
from .models import Post, Category

class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'content', 'category', 'is_published']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 10}),
'category': forms.Select(attrs={'class': 'form-control'}),
'is_published': forms.CheckboxInput(attrs={'class': 'form-check-
input'}),
}

def clean_title(self):
title = self.cleaned_data.get('title')
if len(title) < 5:
raise forms.ValidationError("Title must be at least 5 characters
long.")
return title

def clean_content(self):
content = self.cleaned_data.get('content')
if len(content) < 50:
raise forms.ValidationError("Content must be at least 50 characters
long.")
return content

# views.py (add to existing views.py)


from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
from django.contrib import messages
from .forms import PostForm

@login_required
def create_post(request):
"""Create a new blog post"""
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
messages.success(request, 'Post created successfully!')
return redirect('blog:post_detail', pk=post.pk)
else:
form = PostForm()

return render(request, 'blog/create_post.html', {'form': form})

# urls.py (add to urlpatterns)


path('post/new/', views.create_post, name='create_post'),

# templates/blog/create_post.html
{% extends 'base.html' %}

{% block title %}Create Post - My Blog{% endblock %}

{% block content %}
<div class="row justify-content-center">
<div class="col-md-8">
<h1>Create New Post</h1>
<form method="post">
{% csrf_token %}

{% for field in form %}


<div class="mb-3">
<label for="{{ field.id_for_label }}" class="form-label">
{{ field.label }}
</label>
{{ field }}
{% if field.help_text %}
<div class="form-text">{{ field.help_text }}</div>
{% endif %}
{% if field.errors %}
<div class="alert alert-danger">
{{ field.errors }}
</div>
{% endif %}
</div>
{% endfor %}

<button type="submit" class="btn btn-primary">Create Post</button>


<a href="{% url 'blog:post_list' %}" class="btn btn-
secondary">Cancel</a>
</form>
</div>
</div>
{% endblock %}
```

Q5. DJANGO ADMIN


----------------
Question: Configure the Django admin interface for your blog models.

Solution:
```python
# admin.py
from django.contrib import admin
from .models import Category, Post
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ['name', 'created_at']
search_fields = ['name']
ordering = ['name']

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ['title', 'author', 'category', 'is_published', 'created_at']
list_filter = ['is_published', 'category', 'created_at']
search_fields = ['title', 'content']
list_editable = ['is_published']
date_hierarchy = 'created_at'

fieldsets = (
('Content', {
'fields': ('title', 'content')
}),
('Metadata', {
'fields': ('author', 'category', 'is_published')
}),
)

def save_model(self, request, obj, form, change):


if not change: # If creating a new post
obj.author = request.user
super().save_model(request, obj, form, change)
```

Q6. DJANGO SETTINGS CONFIGURATION


---------------------------------
Question: Explain key settings in Django's settings.py file.

Solution:
```python
# settings.py (key sections)

# SECURITY SETTINGS
SECRET_KEY = 'your-secret-key-here'
DEBUG = True # Set to False in production
ALLOWED_HOSTS = ['localhost', '127.0.0.1']

# DATABASE CONFIGURATION
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}

# INSTALLED APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # Your app
]

# MIDDLEWARE
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# TEMPLATES
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

# STATIC FILES
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = BASE_DIR / 'staticfiles'

# MEDIA FILES
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
```

Q7. DJANGO MIGRATIONS


---------------------
Question: Explain Django migrations and how to create/manage them.

Solution:
```bash
# Creating migrations
python manage.py makemigrations

# Applying migrations
python manage.py migrate

# Checking migration status


python manage.py showmigrations

# Creating a specific migration


python manage.py makemigrations blog

# Applying a specific migration


python manage.py migrate blog 0001

# Rolling back migrations


python manage.py migrate blog 0001 # Go back to migration 0001
```

Migration Example:
```python
# Generated migration file (migrations/0001_initial.py)
from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name='Category',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True,
serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('description', models.TextField(blank=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
],
options={
'verbose_name_plural': 'Categories',
},
),
migrations.CreateModel(
name='Post',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True,
serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=200)),
('content', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('is_published', models.BooleanField(default=False)),
('author',
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.user')),
('category', models.ForeignKey(null=True,
on_delete=django.db.models.deletion.SET_NULL, to='blog.category')),
],
options={
'ordering': ['-created_at'],
},
),
]
```

Q8. DJANGO TESTING


------------------
Question: Write basic tests for your blog models and views.

Solution:
```python
# tests.py
from django.test import TestCase, Client
from django.contrib.auth.models import User
from django.urls import reverse
from .models import Category, Post

class BlogModelTest(TestCase):
def setUp(self):
self.user = User.objects.create_user(
username='testuser',
password='testpass123'
)
self.category = Category.objects.create(
name='Technology',
description='Tech related posts'
)
self.post = Post.objects.create(
title='Test Post',
content='This is a test post content.',
author=self.user,
category=self.category,
is_published=True
)

def test_category_str(self):
self.assertEqual(str(self.category), 'Technology')

def test_post_str(self):
self.assertEqual(str(self.post), 'Test Post')

def test_post_ordering(self):
post2 = Post.objects.create(
title='Newer Post',
content='This is a newer post.',
author=self.user,
is_published=True
)
posts = Post.objects.all()
self.assertEqual(posts[0], post2) # Newer post should come first

class BlogViewTest(TestCase):
def setUp(self):
self.client = Client()
self.user = User.objects.create_user(
username='testuser',
password='testpass123'
)
self.category = Category.objects.create(name='Technology')
self.post = Post.objects.create(
title='Test Post',
content='Test content',
author=self.user,
category=self.category,
is_published=True
)

def test_home_view(self):
response = self.client.get(reverse('blog:home'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Test Post')

def test_post_list_view(self):
response = self.client.get(reverse('blog:post_list'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Test Post')

def test_post_detail_view(self):
response = self.client.get(reverse('blog:post_detail',
args=[self.post.pk]))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Test Post')
self.assertContains(response, 'Test content')

def test_create_post_view_requires_login(self):
response = self.client.get(reverse('blog:create_post'))
self.assertEqual(response.status_code, 302) # Redirect to login

def test_create_post_view_with_login(self):
self.client.login(username='testuser', password='testpass123')
response = self.client.get(reverse('blog:create_post'))
self.assertEqual(response.status_code, 200)

# Running tests
# python manage.py test
# python manage.py test blog
# python manage.py test blog.tests.BlogModelTest
```

PRACTICAL EXERCISES:
====================

Exercise 1: Add Search Functionality


-----------------------------------
```python
# views.py
def search_posts(request):
query = request.GET.get('q', '')
if query:
posts = Post.objects.filter(
Q(title__icontains=query) | Q(content__icontains=query),
is_published=True
)
else:
posts = Post.objects.none()

return render(request, 'blog/search.html', {


'posts': posts,
'query': query
})

# urls.py
path('search/', views.search_posts, name='search_posts'),
```

Exercise 2: Add Comments System


------------------------------
```python
# models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE,
related_name='comments')
author_name = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
is_approved = models.BooleanField(default=False)

class Meta:
ordering = ['created_at']
```

KEY CONCEPTS TO REMEMBER:


=========================

1. **MVT Pattern**: Model (data), View (logic), Template (presentation)


2. **URL Patterns**: Define routing for your application
3. **Models**: Define database structure and relationships
4. **Views**: Handle business logic and return responses
5. **Templates**: Define HTML structure and presentation
6. **Forms**: Handle user input and validation
7. **Admin**: Built-in administration interface
8. **Migrations**: Database schema version control

BEST PRACTICES:
===============

1. Use meaningful model field names


2. Implement proper form validation
3. Use template inheritance for consistency
4. Write tests for your code
5. Use environment variables for sensitive settings
6. Follow Django naming conventions
7. Use class-based views when appropriate
8. Implement proper error handling

You might also like