Reputation: 1808
So I have a social network where users can post thinks. I would like to incorporate a blog system into the same feed
app instead of making blog its own app. I was thinking that if I (or someone with adequate permissions) wanted to make a blog post they could use the same form used by everyone to make a post, however since they have higher permissions they would be shown an extra option on the form that allows them to make it a blog post. and on the blog page I would just filter out to only have posts with blog_post
set to true to be shown.
I tried to do this with a simple if statement in the forms.py however I get an error:
Traceback (most recent call last):
File "/anaconda/envs/test/lib/python3.6/site-packages/django/utils/autoreload.py", line 228, in wrapper
fn(*args, **kwargs)
File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
self.check(display_num_errors=True)
File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/management/base.py", line 359, in check
include_deployment_checks=include_deployment_checks,
File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/management/base.py", line 346, in _run_checks
return checks.run_checks(**kwargs)
File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/checks/registry.py", line 81, in run_checks
new_errors = check(app_configs=app_configs)
File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/checks/urls.py", line 16, in check_url_config
return check_resolver(resolver)
File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/checks/urls.py", line 26, in check_resolver
return check_method()
File "/anaconda/envs/test/lib/python3.6/site-packages/django/urls/resolvers.py", line 254, in check
for pattern in self.url_patterns:
File "/anaconda/envs/test/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/anaconda/envs/test/lib/python3.6/site-packages/django/urls/resolvers.py", line 405, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/anaconda/envs/test/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/anaconda/envs/test/lib/python3.6/site-packages/django/urls/resolvers.py", line 398, in urlconf_module
return import_module(self.urlconf_name)
File "/anaconda/envs/test/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "/Users/garrettlove/Desktop/evverest/evverest/urls.py", line 20, in <module>
from feed import views
File "/Users/garrettlove/Desktop/evverest/feed/views.py", line 4, in <module>
from feed.forms import PostForm,CommentForm
File "/Users/garrettlove/Desktop/evverest/feed/forms.py", line 7, in <module>
class PostForm(forms.ModelForm):
File "/anaconda/envs/test/lib/python3.6/site-packages/django/forms/models.py", line 248, in __new__
"needs updating." % name
django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited; form PostForm needs updating.
forms.py:
from django.contrib.auth import get_user_model
User = get_user_model()
class PostForm(forms.ModelForm):
class Meta:
model = UserPost
if User.username == 'garrett':
fields = ('title','image','post_body','blog_post')
else:
fields = ('title','image','post_body')
widget = {
'title':forms.TextInput(attrs={'class':'post-title'}),
'post_body':forms.Textarea(attrs={'class':'post-body'}),
}
models.py:
from django.contrib.auth import get_user_model
User = get_user_model()
# Create your models here.
class UserPost(models.Model):
author = models.ForeignKey(User,related_name='userpost',null=True)
post_date = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=150,blank=False)
post_body = models.TextField(max_length=1000,blank=False)
image = models.ImageField(upload_to='post_pics',blank=True)
blog_post = models.BooleanField(default=False)
class Meta:
ordering = ['-post_date']
def publish(self):
self.save()
def get_absolute_url(self):
return reverse('index')
def __str__(self):
return self.title
Views.py:
from django.shortcuts import render,get_object_or_404,redirect
from django.utils import timezone
from feed.models import UserPost,UserComment
from feed.forms import PostForm,CommentForm
from django.urls import reverse_lazy
from django.contrib.auth.decorators import login_required
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import LoginRequiredMixin
from braces.views import SelectRelatedMixin
from django.views.generic import (TemplateView,ListView,
DetailView,CreateView,
UpdateView,DeleteView)
User = get_user_model()
# Create your views here.
##Posts Views
class HomeView(LoginRequiredMixin,ListView):
login_url = 'account_login'
model = UserPost
class CreatePostView(LoginRequiredMixin,CreateView):
login_url = 'users:user_login'
redirect_field_name = '/userpost_list.html'
model = UserPost
form_class = PostForm
def form_valid(self,form):
form.instance.author = self.request.user
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return super(CreatePostView, self).form_valid(form)
class PostDetailView(DetailView):
model = UserPost
post_comments = UserComment.objects.all()
context = {
'post':model,
'comments':post_comments,
}
class UpdatePostView(LoginRequiredMixin,UpdateView):
login_url = '/login/'
model = UserPost
fields = [
'title',
'post_body',
]
template_name_suffix = '_edit_form'
def get_success_url(self):
postid = self.kwargs['pk']
return reverse_lazy('index')
@login_required
def DeletePost(request,pk):
post = get_object_or_404(UserPost,pk=pk)
post.delete()
return redirect('index')
##Comments Views
@login_required
def add_comment_to_post(request,pk):
post = get_object_or_404(UserPost,pk=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.author = request.user
comment.save()
return redirect('feed:post_detail', pk=post.pk)
else:
form = CommentForm()
return render(request,'feed/comment_form.html',{'form':form})
@login_required
def comment_remove(request,pk):
comment = get_object_or_404(UserComment,pk=pk)
post_pk = comment.post.pk
comment.delete()
return redirect('feed:post_detail',pk=post_pk)
##BLOG VIEWS
class BlogView(ListView):
model = UserPost
Upvotes: 0
Views: 77
Reputation:
in your view need add user to kwargs:
class CreatePostView(LoginRequiredMixin,CreateView):
# Your code here
def get_form_kwargs(self):
kwargs = super(CreatePostView, self).get_form_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
after it use __init__
method (i correct it with Daniel solution)
class PostForm(forms.ModelForm):
class Meta:
model = UserPost
fields = ('title','image','post_body','blog_post')
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(PostForm, self).__init__(*args, **kwargs)
if not user.username == 'garrett':
self.fields.pop('blog_post')
Upvotes: 2
Reputation: 600059
This can't possibly work in this way. This is all evaluated when the class is defined, long before there are any users. And User
is the class itself, not an instance of it; User.username
is just a CharField object, not an actual username.
Instead, you need to set the full list of fields as default, but in the form's __init__
method you take the current user and modify the actual fields as necessary.
class PostForm(forms.ModelForm):
class Meta:
model = UserPost
fields = ('title','image','post_body','blog_post')
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(PostForm, self).__init__(*args, **kwargs)
if user.username != 'garrett'
del self.fields['blog_post']
Upvotes: 1