在Django中正确设计,以根据用户类型处理表单和视图

时间:2019-05-11 22:22:35

标签: python django

问题

我正在用Django编写一个将学生与导师联系起来的应用程序。有三种主要模型:StudentTutorCoordinator

问题在于,这三种模型的网站本身都非常相似,但是每种模型在实际操作或查看方法上都有所不同。

例如,所有三种类型的用户都可以通过BookClassForm预订课程。但是,Coordinator可以分配一名导师和学生,而一名导师和学生则不能。例如,Coordinator可以在日历视图中查看所有学生和导师的所有课程,而一个学生只能看到他的课程。

通常,这是否意味着我应该编写三种单独的形式或一种使每种类型的用户可选的输入形式?我要编写三种模板还是为每种类型的用户放置一个逻辑的模板?我编写三个视图来处理每种类型的用户还是一个主视图?我要为每种类型的用户编写一个应用程序还是为一个主应用程序编写一个应用程序?

我最终要开发出这个具有很多视图和重复代码的非常大的应用程序,我真的不知道正确的做法是什么。


我已经尝试了一些方法来尽可能解决此问题:

选项1

第一个选项非常幼稚,我只维护一个urls.py文件,并在视图上进行逻辑处理。类似于:

# views.py
def classes_view(request):
   if request.user.is_superuser:
     # a coordinator
     return render(request, "classes.html", {'classes': Class.objects.all()})
   try:
      if request.user.tutor:
        return render(request, "classes.html", {'classes': Class.objects.filter(tutor=request.user.tutor))
    except Tutor.DoesNotExist:
        return render(request, "classes.html", {'classes': Class.objects.filter(student=request.user.student))

问题是我正在数十个视图上编写此样板代码。

选项2

将项目分为三个应用程序(学生,导师,协调员),并分别处理视图。恐怕此选项会导致很多代码重复,但是我可能错了。我看到的另一个不便之处是,当三个应用程序要与第四个普通应用程序交互时会发生什么?

例如,我创建一个notifications应用程序,该应用程序处理应用程序中通知的所有逻辑和模型。会有这样的urls.py

urlpatterns = [
    url(r'delete-notification/(?P<pk>\d+)$', NotificationDelete.as_view(), name='delete-notification'),
    url(r'notification/(?P<pk>\d+)$', NotificationView.as_view(), name='notifications'),
]

现在,如果我想将其与协调员和学生联系在一起,则需要添加以下内容:

# coordinator/urls.py
urlpatterns = [
    url(r'^notifications/', include('notifications.urls')),
    url(r'^tutors/', TutorsView.as_view(), name='tutors'),
]

# student/urls.py
urlpatterns = [
    url(r'^notifications/', include('notifications.urls')),
    url(r'^my-classes/', ClassesView.as_view(), name='classes'),
]

但是如果我想在通知应用程序中内部添加逻辑(取决于用户类型)怎么办?如果我想为Coordinator软删除通知并为Student硬删除通知怎么办?我将逻辑放在哪里?我觉得通知应用程序在所有这些方面都是独立的。


我不知道,我很困惑。

非常感谢您的帮助。

谢谢。

1 个答案:

答案 0 :(得分:0)

创建三个用户组,将相应的用户分配给相应的组,并授予他们必要的权限。

代表您的问题, 将有3个用户组,即 导师,学生和协调员

注册时,请检查用户是学生,导师还是协调员。

models.py

from django.contrib.auth.models import AbstractUser

checking_choices = (
    ('student', 'Student'),
    ('tutor', 'Tutor'),
    ('coordinator', 'Coordinator'),
)

class User(AbstractUser):
    student_or_tutor_coordinator = models.CharField(max_length=12, choices=checking_choices, blank=True)

上述模型将在用户注册时添加一个额外的字段

forms.py

from .model import User
from django.contrib.auth.forms import UserCreationForm


class SignupForm(UserCreationForm):
    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2', 'student_or_tutor_coordinator')

视图功能注册并代表用户使用的选项添加


def signup(request):
    User = get_user_model()
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            checker = form.data.get('student_or_tutor_coordinator')
            if (checker == 'student'):
                 user = form.save(commit=False)
                 user.save()
                 group = Group.objects.get(name='Student')
                 user.groups.add(group)

            elif (checker == 'tutor'):
                 user = form.save(commit=False)
                 user.save()
                 group = Group.objects.get(name='Tutor')
                 user.groups.add(group)     

            if (checker == 'coordinator'):
                 user = form.save(commit=False)
                 user.save()
                 group = Group.objects.get(name='Coordinator')
                 user.groups.add(group)

    else :
        form = SignupForm()
    return render(request, 'regform.html', {'form': form})   

在登录时与用户组进行检查并创建相应的模板。创建仪表板和仪表板视图。


def dashboard(request):

    Student = Group.objects.get(name='Student')
    Tutor = Group.objects.get(name='Tutor')
    Cooridnator = Group.objects.get(name='Coordinator')

    if request.user in Student.user_set.all():
        ...
        ...
        #yourcode
        return render(request, 'studenttdashboard.html')

    elif request.user in Tutor.user_set.all():
        ...
        ...
        #yourcode
        return render(request, 'tutordashboard.html')

    elif request.user in Coordinator.user_set.all():
        ...
        ...
        #yourcode
        return render(request, 'coordinatordashboard.html')

可以在django管理门户中为每个组分配模型权限。