试图在 STUDENT 模型(外键)中保存 POST 数据 CLASS NAME?

Posted

技术标签:

【中文标题】试图在 STUDENT 模型(外键)中保存 POST 数据 CLASS NAME?【英文标题】:Trying to save POST data CLASS NAME in STUDENT model (foreign key)? 【发布时间】:2018-05-24 03:27:17 【问题描述】:

我正在尝试在页面上以表单形式显示类。当点击注册按钮时,我得到班级名称并将其分配给学生模型(它具有班级模型的外键)..

更新:

新错误:/enrol/ 处的 ValueError 无法分配“'guitar101'”:“StudentProfile.student_class”必须是“MusicClass”实例。

django 新手,我不知道自己在做什么,请帮忙! 我的尝试,有什么问题?

models.py

class StudentProfile(models.Model):
    user = models.OneToOneField('Accounts', related_name='student_profile')
    student_class = models.ForeignKey(to=MusicClass, related_name="student_class", null=True, blank=True)
    is_student = models.BooleanField('student status', default=True)
     # more fields


class MusicClass(models.Model):
    class_name = models.CharField(max_length=500, blank=True)
    # more fields 

views.py

# enrolls student
def studentEnrol(request):

    if request.method == "POST":
       musicClass     = request.POST.get('musicClass', '')
       student_profile  = StudentProfile(student_class=musicClass)
       student_profile.save()
       return HttpResponseRedirect('/') 


    else:    
        querySet = MusicClass.objects.all()
        args = 'classes': querySet 

    return render(request, 'accounts/enrol.html', args)

forms.py

class MusicClassesEnrolForm(forms.ModelForm):
    class Meta:
        model = MusicClass
        fields = ('class_name', 'class_level', 'class_time', 'class_room', 'instrument_taught', 'day', 'teacher')

enrol.html

 % extends 'base.html' %

 % block body %
 <div class="outer"><div class="container">
     <h1> Enrol into Class </h1>

    <table style="width:100%">
      <tr>
        <th>Class Name</th>
        <th>Instrument</th> 
        <th>Class Level</th>
        <th>Time</th>
        <th>Teacher</th>
        <th>Room</th>
        <th>Register</th>
      </tr><br>
        % for class in classes %

          <tr>
            <td> class.class_name </td>
            <td> class.instrument_taught </td>
            <td> class.class_level </td>
            <td> class.class_time </td>
            <td> class.teacher </td>
            <td> class.class_room </td>
            <td><form method="post">
                % csrf_token %
                <input type="hidden" name="musicClass" value=" class.class_name ">
                <input type="submit" name="enrolBtn" value="Enrol">
            </form></td>
          </tr>

        % endfor %
     <table>


    </p>

</div>
</div>
% include "footer.html" %
% endblock %

请出主意?

更新 - 添加追溯

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/enrol/

Django Version: 1.11.7
Python Version: 3.6.5
Installed Applications:
['accounts',
 'timetable',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\Users\N9587268\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
  41.             response = get_response(request)

File "C:\Users\N9587268\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\N9587268\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "D:\ifb299\webrepo\musicwebsite\website\accounts\views.py" in studentEnrol
  127.        StudentProfile = StudentProfile(student_class=musicClass)

Exception Type: UnboundLocalError at /enrol/
Exception Value: local variable 'StudentProfile' referenced before assignment

请求信息 POST(例如,这是我在点击注册 btn 时从帖子中获得的信息)

csrfmiddlewaretoken 
'TY28RiLjhtu98v8uthXFuCGJ4pPO3z6e02IDa6x8UFujenzEZdECunhxuqcAKtCw'
musicClass  
'guitar101'
enrolBtn    
'Enrol'

【问题讨论】:

这里使用之前没有导入StudentProfile模型:StudentProfile(student_class=musicClass) 您是否在您的views.py 中导入了StudentProfileStudentProfile = StudentProfile(student_class=musicClass) 也没有意义。您正在尝试重新分配类定义。选择不同的变量名,通常的约定是snake_case,即student_profile = StudentProfile(...) 从 accounts.models 导入 Accounts,StudentProfile 将其导入。这行在这里:StudentProfile(student_class=musicClass) 我什至不确定这是否是你所做的......我正在尝试将 class_name 分配给学生......你能给我一个例子吗 所以错误是因为StudentProfile 不存在。你能告诉我们你在哪里添加这行from accounts.models import Accounts, StudentProfile,它和你的视图在同一个文件中吗? 在更改为snake_case(即student_profile)后,好的错误消失了……但是新错误:无法分配“'guitar101'”:“StudentProfile.student_class”必须是“MusicClass”实例。 @塞尔丘克 【参考方案1】:

现在您尝试将 string 分配给不正确的 ForeignKey 字段。 获得musicClass = request.POST.get('musicClass', '') 后,您应该拥有或创建一个MusicClass 实例

我用get_or_create

# @login_required # A login decorator is very important here
def studentEnrol(request):
    user = request.user
    if not hasattr(user,'student_profile'): 
         # The current user doesn't have student_profile attribute
         # redirect to the page you want
         return redirect('completeProfile') # for instance
    student_profile = request.user.student_profile
    if request.method == "POST":
         id_musicClass     = request.POST.get('musicClass')
         music_class = MusicClass.objects.get(id=id_musicClass)
         # or music_class = get_object_or_404(MusicClass,id=id_musicClass)
         student_profile.student_class = music_class
         student_profile.save()
         return HttpResponseRedirect('/') 
    else:
        '''rest of the codes'''

【讨论】:

我明白了,我已经粘贴了您的解决方案,得到:IntegrityError at /enrol/ (1048, "Column 'user_id' cannot be null") 想法? 这可能是由于创建了一个我需要参考的抽象用途,这里是用户模型:imgur.com/a/rvzslzY 仅仅因为你的模型class StudentProfile(models.Model): user = models.OneToOneField('Accounts', related_name='student_profile')中的这一行,在创建StudentProfile时,你还必须使用用户实例模型分配帐户 我更新了我的答案:如果当前用户已登录,那么您应该将user 分配给当前登录的用户user=request.user,就像这样StudentProfile(student_class=music_class,user=request.user) 对,它有点工作,用另一个用户配置文件再次测试,但出现此错误:IntegrityError at /enrol/ (1062, "Duplicate entry '7' for key 'user_id'")【参考方案2】:

musicClass 变量包含MusicClass 对象的id,而不是实例本身:

musicClass     = request.POST.get('musicClass', '')
student_profile  = StudentProfile(student_class=musicClass)

为了将其分配给student_class 字段,您需要该实例。试试这个:

music_class_id = int(request.POST.get('musicClass'))
music_class = MusicClass.objects.get(pk=music_class_id)
student_profile  = StudentProfile(student_class=music_class)

并更改以下行

<input type="hidden" name="musicClass" value=" class.class_name ">

<input type="hidden" name="musicClass" value=" class.id ">

【讨论】:

试试 printing music_class_idmusic_class。它们是否包含任何数据?

以上是关于试图在 STUDENT 模型(外键)中保存 POST 数据 CLASS NAME?的主要内容,如果未能解决你的问题,请参考以下文章

Django模型基于外键自动递增主键

数据模型续

Django 使用外键添加到数据库,同时仍显示来自其他模型的信息

thinkphp5 模型表关联

Flask:06-一首歌的时间掌握flask数据模型(02)

删除没有外键警告的 django 模型类对象