Django: Вставка, редактирование, удаление статей
Здесь я выложил работающий скрипт, оусществляющий действия со статьями.
Итак, есть приложение articles (статьи, которые можно править зарегистрированным пользователям, не входя в админку)
Каждая статья принадлежит какому-нибудь разделу. Разделы добавляются и изменяются в админке.
Для того, чтобы не изобретать велосипед по созданию меню, разработке CSS и пр. я использую стороннее приложение django-bootstrap3. Возможности этого пакета планируется описать в одной из статей.
articles/models.py
from django.db import models
from django.contrib import admin
from django.utils import timezone
from rte import RTEField
from django.urls import reverse
class Razdel(models.Model):
name = models.CharField(max_length=50, unique = True)
def __unicode__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=150,verbose_name = 'Название статьи')
body = RTEField(default = '')
timestamp = models.DateTimeField(default = timezone.now, db_index = True, verbose_name = "Опубликована")
razdel = models.ForeignKey(Razdel,on_delete=models.SET_NULL,blank=True,null=True,verbose_name = 'Раздел')
def get_absolute_url(self):
return reverse('article', args=[str(self.id)])
def get_list_url(self):
return reverse('articles', args=[str(self.razdel.id)])
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title','timestamp','razdel')
admin.site.register(Article,ArticleAdmin)
class RazdelAdmin(admin.ModelAdmin):
list_display = ['name']
admin.site.register(Razdel,RazdelAdmin)
articles/views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from .models import Article, Razdel
from django.views.generic import ListView, DetailView
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.views.generic.edit import CreateView,UpdateView, DeleteView
from django.core.urlresolvers import reverse
from .forms import ArticleForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.urlresolvers import reverse_lazy
class ListArticles(ListView):
template_name = 'articles.html'
model = Article
def get_context_data(self, **kwargs):
context = super(ListArticles, self).get_context_data(**kwargs)
page = self.request.GET.get("page")
razdel_id = self.kwargs.get('razdel',0)
articles = Article.objects.filter(razdel=razdel_id).order_by ('title')
current_page = Paginator(articles, 8)
try:
context['articles'] = current_page.page(page)
except PageNotAnInteger:
context['articles'] = current_page.page(1)
except EmptyPage:
context['articles'] = current_page.page(current_page.num_pages)
context['curr_razdel'] = Razdel.objects.get(id=razdel_id)
return context
class ArticleDetailView(DetailView):
model = Article
template_name = "article.html"
def get_context_data(self, **kwargs):
context = super(ArticleDetailView, self).get_context_data(**kwargs)
return context
class ArticleNew(LoginRequiredMixin,CreateView):
form_class = ArticleForm
template_name = "article_add.html"
class ArticleUpdate(LoginRequiredMixin,UpdateView):
model = Article
form_class = ArticleForm
template_name = 'article_update.html'
class ArticleDelete(LoginRequiredMixin,DeleteView):
model = Article
template_name = 'article_delete.html'
def get_object(self, *args, **kwargs):
object = super(ArticleDelete,self).get_object(*args, **kwargs)
self.success_url = reverse_lazy('articles',kwargs={'razdel': object.razdel.id})
return object
articles/urls.py
from django.conf.urls import url
from . import views
from .models import Article
from .forms import ArticleForm
urlpatterns = [
url(r'^(?P\d+)/',views.ListArticles.as_view(),name='articles'),
url(r'^article/(?P\d+)/$',views.ArticleDetailView.as_view(),name='article'),
url(r'^new/$',views.ArticleNew.as_view(),name='articlenew'),
url(r'^article/(?P\d+)/edit$',views.ArticleUpdate.as_view(),name='articleedit'),
url(r'^article/(?P\d+)/delete$',views.ArticleDelete.as_view(),name='articledelete'),
]
articles/templates/article_add.html
Шаблоны article_update и article_delete - как близнецы - братья. Можно при желании их соединить в один шаблон.
Только надо разобраться, как передать в шаблон тип действия (вставка, редактирование или удаление).
{% extends "main.html" %}
{% load bootstrap3 %}
{% block content %}
{% bootstrap_messages %}
<h1>Новая статья</h1>
<form action="" method="POST" class="form">{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="btn btn-primary">{% bootstrap_icon "star" %} Создать </button>
</form>
{% endblock %}