5
\$\begingroup\$

I want to learn how to create websites and I have started learning Django web framework. I think Django is very good alternative for PHP and it isn't too complex as JEE. I'm very satisfied learning Django framework. So, within the framework of science I made a blog in Django. I would receive an opinion about quality of my code (views, urls, models, forms):

views.py:

from django.core.mail import send_mail
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Count
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView
from haystack.query import SearchQuerySet
from taggit.models import Tag
from .forms import EmailPostForm, CommentForm, SearchForm
from .models import Post, Comment

# Create your views here.
class PostListView(ListView):
    queryset = Post.published.all()
    context_object_name = 'posts'
    paginate_by = 3
    template_name = 'blog/post/list.html'

def post_list(request, tag_slug=None):
    object_list = Post.published.all()
    tag = None

    if tag_slug:
        tag = get_object_or_404(Tag, slug=tag_slug)
        object_list = object_list.filter(tags__in=[tag])

    paginator = Paginator(object_list, 3) # Trzy posty na każdej stronie.
    page = request.GET.get('page')
    try:
        posts = paginator.page(page)
    except PageNotAnInteger:
        # Jeżeli zmeinna page nie jest liczbą całkowitą,
        # wówczas pobierana jest pierwsza strona wyników.
        posts = paginator.page(1)
    except EmptyPage:
        # Jeżeli zmienna page ma wartość większą niż numer ostatniej strony
        # wyników, wtedy pobierana jest ostatnia strona wyników.
        posts = paginator.page(paginator.num_pages)
    return render(request,
            'blog/post/list.html',
            {'page': page,
            'posts': posts,
            'tag': tag})

def post_detail(request, year, month, day, post):
    post = get_object_or_404(Post, slug=post,
            status='published',
            publish__year=year,
            publish__month=month,
            publish__day=day)

    # Lista aktywnych komentarzy dla danego posta.
    comments = post.comments.filter(active=True)

    if request.method == 'POST':
        # Komentarz został opublikowany.
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            # Utworzenie obiektu Comment, ale jeszcze nie zapisujemy go w bazie danych.
            new_comment = comment_form.save(commit=False)
            # Przypisanie komentarza do bieżącego posta.
            new_comment.post = post
            # Zapisanie komentarza w bazie danych.
            new_comment.save()
    else:
        comment_form = CommentForm()

    # Lista podobnych postów.
    post_tags_ids = post.tags.values_list('id', flat=True)
    similar_posts = Post.published.filter(tags__in=post_tags_ids)\
            .exclude(id=post.id)
    similar_posts = similar_posts.annotate(same_tags=Count('tags'))\
            .order_by('-same_tags','-publish')[:4]

    return render(request,
            'blog/post/detail.html',
            {'post': post,
                'comments': comments,
                'comment_form': comment_form,
                'similar_posts': similar_posts})

def post_share(request, post_id):
    # Pobranie posta na podstawie jego identyfikatora.
    post = get_object_or_404(Post, id=post_id, status='published')
    sent = False

    if request.method == 'POST':
        # Formularz został wysłany.
        form = EmailPostForm(request.POST)
        if form.is_valid():
            # Weryfikacja pól formularza zakończyła się powodzeniem...
            cd = form.cleaned_data
            post_url = request.build_absolute_uri(
                    post.get_absolute_url())
            subject = '{} ({}) zachęca do przeczytania "{}"'.format(cd['name'], cd['email'], post.title)
            message = 'Przeczytaj post "{}" na stronie {}\n\n Komentarz dodany przez {}: {}'.format(post.title, post_url, cd['name'], cd['comments'])
            send_mail(subject, message, 'admin@myblog.com', [cd['to']])
            sent = True
    else:
        form = EmailPostForm()
    return render(request, 'blog/post/share.html', {'post': post,
        'form': form,
        'sent': sent})

def post_search(request):
    form = SearchForm()
    if 'query' in request.GET:
        form = SearchForm(request.GET)
        if form.is_valid():
            cd = form.cleaned_data
            results = SearchQuerySet().models(Post)\
                    .filter(content=cd['query']).load_all()
            # Obliczenie całkowitej liczby wyników.
            total_results = results.count()
            return render(request,
                    'blog/post/search.html',
                    {'form': form,
                        'cd': cd,
                        'results': results,
                        'total_results': total_results})
    else:
        return render(request,
                'blog/post/search.html',
                {'form': form})

forms.py:

from django import forms
from .models import Comment

class EmailPostForm(forms.Form):
    name = forms.CharField(max_length=25)
    email = forms.EmailField()
    to = forms.EmailField()
    comments = forms.CharField(required=False,
            widget=forms.Textarea)

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('name', 'email', 'body')

class SearchForm(forms.Form):
    query = forms.CharField()

urls.py:

from django.conf.urls import url
from . import views
from .feeds import LatestPostsFeed

urlpatterns = [
        # Widoki posta.
        url(r'^$', views.post_list, name='post_list'),
        #url(r'^$', views.PostListView.as_view(), name='post_list'),
        url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/'\
                r'(?P<post>[-\w]+)/$',
                views.post_detail,
                name='post_detail'),
        url(r'^(?P<post_id>\d+)/share/$', views.post_share,
            name='post_share'),
        url(r'^tag/(?P<tag_slug>[-\w]+)/$', views.post_list,
            name='post_list_by_tag'),
        url(r'^feed/$', LatestPostsFeed(), name='post_feed'),
        url(r'^search/$', views.post_search, name='post_search'),
        ]

models.py:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from taggit.managers import TaggableManager

# Create your models here.
class PublishedManager(models.Manager):
    def get_queryset(self):
        return super(PublishedManager,
                self).get_queryset()\
                        .filter(status='published')

class Post(models.Model):
    STATUS_CHOICES = (
            ('draft', 'Roboczy'),
            ('published', 'Opublikowany'),
            )
    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250,
            unique_for_date='publish')
    author = models.ForeignKey(User,
            related_name='blog_posts')
    body = models.TextField()
    publish = models.DateTimeField(default=timezone.now)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=10,
            choices=STATUS_CHOICES,
            default='draft')
    objects = models.Manager()  # Menedżer domyślny
    published = PublishedManager()  # Menedżer niestandardowy
    tags = TaggableManager()

    class Meta:
        ordering = ('-publish',)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('blog:post_detail',
                args=[self.publish.year,
                    self.publish.strftime('%m'),
                    self.publish.strftime('%d'),
                    self.slug])

class Comment(models.Model):
    post = models.ForeignKey(Post, related_name='comments')
    name = models.CharField(max_length=80)
    email = models.EmailField()
    body = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    active = models.BooleanField(default=True)

    class Meta:
        ordering = ('created',)

    def __str__(self):
        return 'Komentarz dodany przez {} dla posta {}'.format(self.name, self.post)
\$\endgroup\$

protected by Community Jan 16 at 8:59

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Browse other questions tagged or ask your own question.