2

我对 Django 很陌生,还在学习它,但我必须创建类似 medium.com 的东西。我想根据用户的兴趣向他们展示帖子。我在注册表单中添加了一个带有复选框的兴趣字段。当然,我在 Post 模型中添加了一个类别。那么,我如何才能显示(仅限登录用户)他们感兴趣的出版物?这是我在帖子应用程序中的 models.py 文件

from django.db import models
from django.utils import timezone
from django.urls import reverse
# Create your models here.
class Post(models.Model):
    CATEGORY = (
        ('sport', 'Sport'),
        ('science', 'Science'),
        ('it', 'IT'),
        ('art', "Art"),
    )

    
    title = models.CharField(verbose_name="Title for publication", max_length=50)
    category = models.CharField(verbose_name="Category", choices=CATEGORY, max_length=50)
    author = models.ForeignKey("accounts.User", verbose_name="Author:", on_delete=models.CASCADE)
    body = models.TextField(verbose_name="Body for publication")
    pub_date = models.DateTimeField(verbose_name="Date:", auto_now_add=True)
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)


    def get_absolute_url(self):
        return reverse("post_detail", kwargs={"pk": self.pk})
    

    def __str__(self):
        return self.title

这是我在帖子应用程序中的 vies.py 文件

from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .models import Post
from django.urls import reverse_lazy

class PostListView(ListView):
    model = Post
    template_name = "index.html"    
    def get_queryset(self):
        return Post.objects.order_by('-pub_date')


class PostDetailView(DetailView):
    model = Post
    template_name = "./posts/post_detail.html"

class PostCreateView(CreateView):
    model = Post
    template_name = "./posts/new_post.html"
    fields = '__all__'

class PostUpdateView(UpdateView):
    model = Post
    template_name = "./posts/update_post.html"
    fields = ['body', 'title', 'category']

class PostDeleteView(DeleteView):
    model = Post
    template_name = "./posts/delete_post.html"
    success_url = reverse_lazy('index')


class SportPostListView(ListView):
    model = Post
    template_name = "./posts/sports.html"

class ITPostListView(ListView):
    model = Post
    template_name = "./posts/it.html"

class SciencePostListView(ListView):
    model = Post
    template_name = "./posts/ilm-fan.html"

class ArtPostListView(ListView):
    model = Post
    template_name = "./posts/sanat.html"

这是我的 index.html 文件

{% extends 'base.html' %}
{% block content %}
{% if object_list %}
    {% for post in object_list %}
        <h1>{{ post.title }}</h1>
        <p>{{ post.pub_date }}</p>
        <p>{{ post.author }}</p>
        <p>{{ post.body }}</p>
        <p>{{ post.category }}</p>
    {% endfor %}
{% else %}
    <p>No posts are available.</p>
{% endif %}
{% endblock content %}

这是我在帐户应用程序中的 forms.py 文件

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.db import models
from django import forms
class SignUpForm(UserCreationForm):
    INTERESTS = (
        ('sport', 'Sport'),
        ('science', 'Science'),
        ('it', 'IT'),
        ('art', "Art"),
        )
    username = forms.CharField(max_length=128, required=True)
    email = models.EmailField(verbose_name='emailingiz', unique=True, default='')
    first_name = forms.CharField(max_length=128, required=True)
    last_name = forms.CharField(max_length=128, required=True)
    interests = forms.MultipleChoiceField(required=True, widget=forms.CheckboxSelectMultiple, choices=INTERESTS)
    USERNAME_FIELD = 'email'

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'username', 'email', 'interests', 'password1', 'password2')
    

最后是帐户应用程序中的这个 views.py 文件

from django.urls import reverse_lazy
from django.views.generic import CreateView
from .forms import SignUpForm

class SignUpView(CreateView):
    form_class = SignUpForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

我不知道该怎么做,但我知道我必须在帖子应用程序的 views.py 文件中做一些事情,但是,我不知道该怎么做。如果您能帮助我,将不胜感激。

4

2 回答 2

1

我会制作另一个模型Category。由于它将是自己的模型,因此您将能够在需要时动态添加未来的类别,而不是硬编码那些choices.

class Category(models.Model):
    name = models.CharField(default=None, blank=True, null=True)

然后你的UserPost模型都会有一个ManytoMany与类别相关的字段。帖子在创建时可以标记为某些类别,用户将能够选择他们感兴趣的多个类别并将它们存储在此字段中:

class User(AbstractBaseUser):
     interests = models.ManytoManyField(Category, default=None, blank=True)
class Post(models.Model):
     categories = models.ManytoManyField(Category, default=None, blank=True)

您可以使用 a forms.modelChoiceFieldwhich 将使您的用户能够选择一个类别。

在您的 PostListView 中,您需要做的就是更改get_queryset过滤用户喜欢的帖子的方法。

class PostListView(ListView):
    model = Post
    template_name = "index.html" 
   
    def get_queryset(self):
        user_interests = self.request.user.interests
        return Post.objects.filter(
        categories__in=user_interests).order_by('pub_date')

然后,您应该获得与用户兴趣共享类别的帖子。

于 2021-01-20T19:29:28.960 回答
1

这是错误

Error during template rendering
In template /home/xesos/projects/mw/mw/templates/base.html, error at line 0

too many values to unpack (expected 2)
1   <!DOCTYPE html>
2   <html lang="en">
3   <head>
4       <meta charset="UTF-8">
5       <meta name="viewport" content="width=device-width, initial-scale=1.0">
6       <style>
7           
8       </style>
9       <title>
10          {% block title %}

为了避免这个错误,我在 forms.py 中做了一些更改,这里是

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms
from posts.models import Category

class SignUpForm(UserCreationForm):
    categories = Category.objects.values_list('name')
    listOfCategory = []
    listOfCategory += categories


    username = forms.CharField(max_length=128, required=True)
    email = forms.EmailField(required=True)
    first_name = forms.CharField(max_length=128, required=True)
    last_name = forms.CharField(max_length=128, required=True)
    USERNAME_FIELD = 'email'
    
    for i in range(0, len(listOfCategory)):
        listOfCategory.append(listOfCategory[i])
    interests = forms.ChoiceField(choices=[(x, x) for x in listOfCategory])

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'username', 'email', 'interests', 'password1', 'password2')
    
    
于 2021-01-21T17:48:25.763 回答