根据用户显示表单字段

时间:2017-09-18 15:50:08

标签: python django forms django-forms

所以我有一个用户可以发帖的社交网络。我想将博客系统整合到同一个feed应用中,而不是将博客作为自己的应用。我在想如果我(或者有足够权限的人)想要发布博客帖子,他们可以使用每个人用来发帖子的相同表格,但是由于他们有更高的权限,他们会在表格上看到一个额外的选项允许他们把它作为博客文章。在博客页面上,我只是过滤掉只有blog_post设置为true才能显示的帖子。

我尝试使用forms.py中的简单if语句执行此操作但是我收到错误:

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

2 个答案:

答案 0 :(得分:2)

在您的视图中

需要将用户添加到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

使用__init__方法后(我用Daniel解决方案更正)

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')

答案 1 :(得分:2)

这不可能以这种方式运作。在定义类之前,在有任何用户之前很久就会对此进行评估。 User是类本身,而不是它的实例; User.username只是一个CharField对象,而不是实际的用户名。

相反,您需要将完整的字段列表设置为默认值,但在表单的__init__方法中,您可以获取当前用户并根据需要修改实际字段。

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']