简体   繁体   English

Django过滤器通过用户名从基于类的通用视图中过滤通用表单Select属性,或预填充并隐藏表单Select-attribute

[英]Django filter generic form Select attribute from generic class-based view by Username or prepopulate and hide the form Select-attribute

I Need to Restrict the Options in a Select Field of a Django Form for not staff users. 我需要限制非工作人员的Django表单的“选择”字段中的选项。

So these are my models.py: 这些是我的models.py:

#!/usr/bin/python3
from django.db import models
from django.urls import reverse


class Extension(models.Model):
    username = models.CharField(primary_key=True, max_length=200, help_text='')
    callerid = models.CharField(max_length=200, help_text='')
    extension = models.CharField(max_length=3, help_text='')
    firstname = models.CharField(max_length=200, help_text='')
    lastname = models.CharField(max_length=200, help_text='')
    password = models.CharField(max_length=200, help_text='')
    context = models.ForeignKey('Context', on_delete=models.SET_NULL, null=True)

    def get_absolute_url(self):
        return reverse('extension-detail', args=[str(self.username)])

    def my_get_absolute_url(self):
        return reverse('my-extension-detail', args=[str(self.username)])

    def __str__(self):
        return self.username


class Context(models.Model):
    name = models.CharField(primary_key=True, max_length=200, help_text='')
    countryprefix = models.CharField(max_length=200, help_text='')
    cityprefix = models.CharField(max_length=200, help_text='')
    number = models.CharField(max_length=200, help_text='')
    extensionsfrom = models.CharField(max_length=200, help_text='')
    extensionstill = models.CharField(max_length=200, help_text='')
    portscount = models.CharField(max_length=200, help_text='')

    def get_absolute_url(self):
        return reverse('context-detail', args=[str(self.name)])

    def my_get_absolute_url(self):
        return reverse('my-context-detail', args=[str(self.name)])

    def __str__(self):
        return self.name

views.py: views.py:

#!/usr/bin/python3
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib.auth.models import Permission
from catalog.models import Extension, Context
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView


class ExtensionCreate(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    model = Extension
    fields = '__all__'
    permission_required = 'catalog.add_extension'


class ExtensionUpdate(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    model = Extension
    fields = '__all__'
    permission_required = 'catalog.change_extension'


class ExtensionDelete(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    model = Extension
    success_url = reverse_lazy('extensions')
    permission_required = 'catalog.delete_extension'

urls.py: urls.py:

#!/usr/bin/python3
from . import views
from django.urls import path


urlpatterns = [
    path('', views.index, name='index'),
    path('extensions/', views.ExtensionListView.as_view(), name='extensions'),
    path('extension/<str:pk>', views.ExtensionDetailView.as_view(), name='extension-detail'),
    path('extension/create/', views.ExtensionCreate.as_view(), name='extension-create'),
    path('extension/<str:pk>/update/', views.ExtensionUpdate.as_view(), name='extension-update'),
    path('extension/<str:pk>/delete/', views.ExtensionDelete.as_view(), name='extension-delete'),
    path('myextensions/', views.ExtensionsByUserListView.as_view(), name='my-extensions'),
    path('myextension/<str:pk>', views.ExtensionsByUserDetailView.as_view(), name='my-extension-detail'),
    path('contexts/', views.ContextListView.as_view(), name='contexts'),
    path('context/<str:pk>', views.ContextDetailView.as_view(), name='context-detail'),
    path('context/create/', views.ContextCreate.as_view(), name='context-create'),
    path('context/<str:pk>/update/', views.ContextUpdate.as_view(), name='context-update'),
    path('context/<str:pk>/delete/', views.ContextDelete.as_view(), name='context-delete'),
    path('mycontexts/', views.ContextByUserListView.as_view(), name='my-contexts'),
    path('mycontext/<str:pk>', views.ContextByUserDetailView.as_view(), name='my-context-detail'),
]

template: 模板:

{% extends "base_generic.html" %}

{% block content %}
  <form action="" method="post">
    {% csrf_token %}
    <table>
    {{ form.as_table }}
    </table>
    <input type="submit" value="Submit">
  </form>
{% endblock %}

In this is how it looks like: 它是这样的: 在此处输入图片说明

The Username is always the same as one of the contexts. 用户名始终与上下文之一相同。
Only Staff User can create a new Context and new Users. 只有职员用户可以创建新的上下文和新用户。
The users then should add their extensions. 然后,用户应添加其扩展名。

While employees should be able to select the context when creating a new extension, customers should only be able to see or select their context in the list. 虽然员工在创建新扩展名时应该能够选择上下文,但是客户应该只能在列表中查看或选择他们的上下文。

Therefore it is needed to filter the Select-attribute for non-staff members so that only the user's context is visible, which is equal to his Username. 因此,需要过滤编外人员的选择属性,以便仅可见用户的上下文,该上下文等于其用户名。

Alternatively, I want to prepopulate and hide the context form field with the Username (=own context) 另外,我想用用户名(= own上下文)预填充并隐藏上下文表单字段

How can I do either of this in the easiest way possible? 如何以最简单的方式来做这两个?

Here is what I tried myself so far: 到目前为止,这是我尝试过的事情:

Like described in this how-to: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms#Renew-book_form_using_a_Form_and_function_view I Defined a Form in forms.py: 就像此操作方法中所述: https : //developer.mozilla.org/zh-CN/docs/Learn/Server-side/Django/Forms#Renew-book_form_using_a_Form_and_function_view我在Forms.py中定义了一个Form

#!/usr/bin/python3
from django import forms
class MyExtensionCreateForm(forms.Form):
    # username = forms.CharField(help_text="")
    # callerid = forms.CharField(help_text="")
    # context = forms.CharField(help_text="")

    firstname = forms.CharField(help_text="")
    lastname = forms.CharField(help_text="")
    extension = forms.CharField(help_text="")
    password = forms.CharField(help_text="")

    def clean_data(self):
        data = self.cleaned_data
        # Remember to always return the cleaned data.
        return data

I then added the folowing to the views.py: 然后,我将以下内容添加到views.py中:

from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.urls import reverse
from catalog.forms import MyExtensionCreateForm

def MyExtensionCreate(request):
    # extension = get_object_or_404(Extension)
    # If this is a POST request then process the Form data
    if request.method == 'POST':
        # Create a form instance and populate it with data from the request (binding):
        form = MyExtensionCreateForm(request.POST)
        # Check if the form is valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            form.firstname = form.cleaned_data['firstname']
            form.lastname = form.cleaned_data['lastname']
            form.extension = form.cleaned_data['extension']
            form.password = form.cleaned_data['password']
            # Prepopulated Fields
            form.context = request.user
            form.callerid = str(form.cleaned_data['firstname'])+" "+str(form.cleaned_data['lastname'])+" "+str(form.cleaned_data['extension'])
            form.username = str(request.user)+"_"+str(form.cleaned_data['extension'])
            form.save()
            # redirect to a new URL:
            return HttpResponseRedirect(reverse('my-extensions'))
    # If this is a GET (or any other method) create the default form.
    else:
        form = MyExtensionCreateForm({'context': request.user})
    context = {
        'form': form,
    }
    return render(request, 'catalog/extension_form-by-user.html', context)

# class MyExtensionCreate(LoginRequiredMixin, CreateView):
#     model = Extension
#     fields = '__all__'
#     form_class = MyExtensionCreateForm


Then I added a new URL to URL patterns in urls.py and added the new Link to the base_generic.html 然后,我在urls.py中的 URL模式中添加了一个新URL,并将新的Link添加到了base_generic.html中。

path('myextensions/create/', views.MyExtensionCreate, name='my-extension-create'),
<li><a href="{% url 'my-extension-create' %}">Add Extension</a></li>

I can view the form, and if I add the context field to the visible form fields, I can see that the context will initially fill with the logged-in username (See First Picture Below). 我可以查看表单,并且如果将上下文字段添加到可见的表单字段中,则可以看到上下文最初将使用登录的用户名填充(请参见下面的第一张图片)。 But as soon as I submit the form I'll get Error's no matter what I try, So basically the GET is working, but the POST isn't really. 但是,无论我尝试什么,只要提交表单,我都会收到错误消息,因此,基本上GET可以正常工作,但是POST并不是真的。

See Folowing Pictures: 请参见以下图片:

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

I was able to Filter the Choices by the Username in the ModelForm but since then I'm not able to save the form to the database anymore. 我可以按ModelForm中的用户名过滤选择,但是从那时起,我再也无法将表单保存到数据库。 Here is the new Stack Post with the Resolution of this Post here and the new Question/Problem. 这是新的Stack Post,此处有此帖子的解决方法,以及新的Question / Problem。 Django: saving the Form does not work (The ModelForm Filters the ForeignKey choices by request.user) Django:无法保存表单(ModelForm通过request.user过滤ForeignKey选择)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Django:尝试了解queryset属性在基于类的通用视图中如何工作 - Django: trying to understand how the queryset attribute works in class-based generic views 如何将表单传递给基于类的通用视图(TodayArchiveView)? - How to pass form to Class-based generic views(TodayArchiveView)? 从基于类的通用视图手动获取响应 - Manually get response from class-based generic view 基于Django类的通用视图“ CreateView”表单错误处理 - Django class based generic view “CreateView” form errors handling Django 基于类的视图处理表单并相应地调整上下文 - Django class-based view processing form and adjusting context accordingly 在扩展基于通用类的CreateView时,访问和保存字段属性中未包括的字段 - Accessing and saving a field that is not included in fields attribute in extending generic class-based CreateView 如何编写基于Django类的视图以用于其他模板的表单显示和提交? - How to write Django class-based view for form displaying and submission from other template? 从基于Django类的视图的form_valid方法调用特殊(非HTTP)URL - Calling a special (non-HTTP) URL from the form_valid method of a Django class-based view 在基于类的视图中自动填写表格 - Automatically filled form in class-based view 不显示基于Django类的表单 - Django Class-based Form is not displayed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM