问题描述
我对 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',)
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
字段。帖子在创建时可以标记为特定类别,用户将能够选择他们感兴趣的多个类别并将它们存储在此字段中:
class User(AbstractBaseUser):
interests = models.ManytoManyField(Category,default=None,blank=True)
class Post(models.Model):
categories = models.ManytoManyField(Category,blank=True)
您可以使用 forms.modelChoiceField
使您的用户能够选择类别。
在您的 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')