Как реализовать шаблоны представления и URL для моделей Post и Category в Django 3 - PullRequest
0 голосов
/ 05 апреля 2020

Я пытаюсь выучить Django, создав простой блог. У меня есть три модели: сообщение, категория и тег.

    class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True, null=False)
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
    updated_on = models.DateTimeField(auto_now=True)
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=POST_STATUS, default=0)
    visibility = models.IntegerField(choices=POST_VISIBILITY, default=0)
    content = models.TextField()
    excerpt = models.TextField()
    category = models.ForeignKey('blog.Category', on_delete=models.CASCADE)
    tags = models.ManyToManyField('blog.Tag')
    image = models.ImageField(upload_to="images/", default=0)

    class Meta:
        ordering = ['-created_on', 'title']
        verbose_name = 'Post'
        verbose_name_plural = 'Posts'
        unique_together = ('title', 'slug')

    def __str__(self):
        return self.title


class Category(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True, null=False)
    description = models.TextField()

    class Meta:
        ordering = ['title']
        verbose_name = 'Category'
        verbose_name_plural = 'Categories'
        unique_together = ('title', 'slug')

    def __str__(self):
        return self.title


class Tag(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True, null=False)
    description = models.TextField()

    class Meta:
        ordering = ['title']
        verbose_name = 'Tag'
        verbose_name_plural = 'Tags'

    def __str__(self):
        return self.title

У меня есть два представления - posts_index показывает все сообщения, а один должен отображать одно сообщение.

from django.shortcuts import render
from .models import Post, Category, Tag


def posts_index(request):
    all_posts = Post.objects.all()
    return render(request, 'index.html', {'posts': all_posts})


def single(request, slug, category):
    single_post = Post.objects.get(slug=slug)
    return render(request, 'single.html', {'single': single_post, 'category_slug': single_post.slug})

В mu urls.py у меня есть следующая конфигурация:

from django.urls import path
from . import views

urlpatterns = [
        path('', views.posts_index, name='index'),
        path('<slug:category_slug>/<slug>/', views.single, name='single')
]

Я добавил несколько категорий (General, Sports ...), и их слагы такие же, как названия, но строчные, то есть общие, спортивные.

Я хочу добиться этого, когда я нажимаю на заголовок записи на моей индексной странице (у меня уже есть это отсортировано в шаблонах), что меня переносят на одну страницу поста блога с URL, который выглядит следующим образом: example.com/category-slug/my-post-slug

В настоящее время я получаю эту ошибку:

TypeError at /general/test-post-we-hope-best/

single() got an unexpected keyword argument 'category_slug'

Request Method:     GET
Request URL:    http://127.0.0.1:8000/general/test-post-we-hope-best/
Django Version:     3.0.5
Exception Type:     TypeError
Exception Value:    

single() got an unexpected keyword argument 'category_slug'

Exception Location:     /Users/XXXXX/XXXXXXX/lib/python3.8/site-packages/django/core/handlers/base.py in _get_response, line 113

Это индекс. html шаблон, который выглядит и работает хорошо, но когда я нажимаю на ссылки, это выдает ошибку, которую я вставил выше.

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
</head>
<body>

    {% for post in posts %}
        <a href="{% url 'single' post.category.slug post.slug%}"><h2>{{post.title}}</h2></a>
        <p>Posted in: {{post.category}}, Posted by: {{post.author}}</p>
        <img height="120px" width="120px" src="{{post.image.url}}" alt="{{post.title}}">
        <p>{{post.excerpt}}</p>
    {% endfor %}

</body>
</html>

Любая помощь будет принята с благодарностью, я на некоторое время застрял на этой.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Там - я смог сам разобраться, вот функция просмотра:

def single(request, slug, category_slug=None):
    single_post = Post.objects.get(slug=slug)
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
    return render(request, 'single.html', {'single': single_post, 'category_slug':category_slug})

И в вашем url.py вы просто передаете его как аргумент, подобный этому:

urlpatterns = [
    path('', views.posts_index, name='index'),
    path('<slug:category_slug>/<slug>/', views.single, name='single')
]
0 голосов
/ 05 апреля 2020
{% url 'single' post_id %}

и если у вас есть два слизняка

{% url 'single' post_id, another_id %}

Сделаю это для вас, но я предлагаю изменить имя URL для чего-то вроде post_details.

...