1. 基於類別的視圖
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import Product
class ProductListView(ListView):
model = Product
template_name = 'products/list.html'
context_object_name = 'products'
paginate_by = 20
def get_queryset(self):
qs = super().get_queryset().filter(is_active=True)
search = self.request.GET.get('q')
if search:
qs = qs.filter(name__icontains=search)
return qs
class ProductDetailView(DetailView):
model = Product
slug_field = 'slug'
template_name = 'products/detail.html'
class ProductCreateView(CreateView):
model = Product
fields = ['name', 'description', 'price', 'category', 'image']
template_name = 'products/form.html'
success_url = reverse_lazy('products:list')
class ProductUpdateView(UpdateView):
model = Product
fields = ['name', 'description', 'price', 'stock']
template_name = 'products/form.html'
class ProductDeleteView(DeleteView):
model = Product
success_url = reverse_lazy('products:list')
2.Django表單
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ['name', 'slug', 'description', 'price', 'category', 'image']
widgets = {
'description': forms.Textarea(attrs={'rows': 4}),
'price': forms.NumberInput(attrs={'min': 0, 'step': '0.01'}),
}
def clean_price(self):
price = self.cleaned_data['price']
if price <= 0:
raise forms.ValidationError('Giá phải lớn hơn 0')
return price
def clean(self):
cleaned_data = super().clean()
name = cleaned_data.get('name')
if name and len(name) < 3:
self.add_error('name', 'Tên phải có ít nhất 3 ký tự')
return cleaned_data
# Contact form (không liên kết model)
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
3. 視圖中的表單
from django.shortcuts import render, redirect
from django.contrib import messages
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# Xử lý form data
send_contact_email(form.cleaned_data)
messages.success(request, 'Gửi thành công!')
return redirect('contact')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
4. 表單集
from django.forms import modelformset_factory, inlineformset_factory
# ModelFormSet
ProductFormSet = modelformset_factory(Product, fields=['name', 'price'], extra=3)
# InlineFormSet (parent-child)
ImageFormSet = inlineformset_factory(
Product, ProductImage,
fields=['image', 'alt_text'],
extra=3,
can_delete=True,
)
5. 文件上傳
def upload_view(request):
if request.method == 'POST':
form = ProductForm(request.POST, request.FILES)
if form.is_valid():
product = form.save()
return redirect('products:detail', slug=product.slug)
else:
form = ProductForm()
return render(request, 'products/form.html', {'form': form})
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_div }}
<button type="submit">Lưu</button>
</form>
下一篇: DRF 序列化器和視圖 — Django REST 框架設定。