(django) 根据用户的兴趣显示帖子
(django) Showing posts according to interests of users
我是 Django 的新手并且还在学习它,但我必须创建类似 medium.com 的东西。我想根据用户的兴趣向他们展示帖子。我在注册表单中添加了一个带有复选框的兴趣字段。当然,我在 Post 模型中添加了一个类别。那么,我怎样才能显示(仅对登录用户)他们感兴趣的出版物?
这是我在 posts app
中的 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 文件中做一些事情,但是,我不知道该怎么做。
如果您能帮助我,将不胜感激。
我会制作另一个模型 Category
。由于它将是自己的模型,您将能够在需要时即时添加未来的类别,而不是让那些硬编码 choices
.
class Category(models.Model):
name = models.CharField(default=None, blank=True, null=True)
那么您的 User
和 Post
模型将各自有一个与类别相关的 ManytoMany
字段。帖子在创建时可以标记为特定类别,用户将能够 select 一些他们感兴趣的类别并将它们存储在该字段中:
class User(AbstractBaseUser):
interests = models.ManytoManyField(Category, default=None, blank=True)
class Post(models.Model):
categories = models.ManytoManyField(Category, default=None, blank=True)
您可以使用 forms.modelChoiceField
使您的用户能够 select 一个类别。
在您的 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')
然后,您应该获取与用户兴趣共享类别的帖子。
这里是错误
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')
我是 Django 的新手并且还在学习它,但我必须创建类似 medium.com 的东西。我想根据用户的兴趣向他们展示帖子。我在注册表单中添加了一个带有复选框的兴趣字段。当然,我在 Post 模型中添加了一个类别。那么,我怎样才能显示(仅对登录用户)他们感兴趣的出版物? 这是我在 posts app
中的 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 文件中做一些事情,但是,我不知道该怎么做。 如果您能帮助我,将不胜感激。
我会制作另一个模型 Category
。由于它将是自己的模型,您将能够在需要时即时添加未来的类别,而不是让那些硬编码 choices
.
class Category(models.Model):
name = models.CharField(default=None, blank=True, null=True)
那么您的 User
和 Post
模型将各自有一个与类别相关的 ManytoMany
字段。帖子在创建时可以标记为特定类别,用户将能够 select 一些他们感兴趣的类别并将它们存储在该字段中:
class User(AbstractBaseUser):
interests = models.ManytoManyField(Category, default=None, blank=True)
class Post(models.Model):
categories = models.ManytoManyField(Category, default=None, blank=True)
您可以使用 forms.modelChoiceField
使您的用户能够 select 一个类别。
在您的 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')
然后,您应该获取与用户兴趣共享类别的帖子。
这里是错误
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')