基于提交到数据库的先前表单字段值的Django 2.1外键设置值

时间:2019-07-18 14:39:05

标签: django

在将我的外键值分配给第一个表单字段值时遇到问题。模型启动是父级,模型团队是子级,具有与启动模型相关的外键,并且startup_name的值必须分配给启动外键字段。但是,团队模型是一个动态字段,其中将多个团队成员插入到模型中,而外键只是一个字段。 我需要帮助以正确完成django编程的新功能

forms.py:

from .models import *
from django import forms

class StartupNameForm (forms.ModelForm):
    class Meta:
        model = Startup
        fields = ['startup_name',]

models.py:

from django.db  import models

class Startup (models.Model):
    startup_name=models.CharField('Startup Name', max_length = 100, unique = True)

    def __str__(self) :
        return self.startup_name

class Team (models.Model):
    name = models.CharField ( 'Name' , max_length = 100 )
    position = models.CharField ( 'Position' , max_length = 100 )
    startup = models.ForeignKey(Startup, on_delete = models.CASCADE, to_field = 'startup_name')

    def __str__(self):
        return self.name

views.py:

def str_dashboard(request) :
    return render ( request , 'str_dashboard.html' )

def startup(request):
    if request.method == 'POST':
        form = StartupNameForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('str_team')
    else:
        form = StartupNameForm()
    return render(request, 'application/str_name.html', {'form': form})

def team(request, self):
    TeamFormset = modelformset_factory(Team, fields = ('name','position'), extra = 1)
    if request.method=='POST':
        formset = TeamFormset(request.POST)
        if formset.is_valid():
            instances = formset.save(commit = False)
            for instance in instances:
                instance.Team.startup = request.session['startup_name']
                instance.save()
            return redirect('str_dashboard')
    else:
        formset = TeamFormset ()
        return render(request,'application/str_team.html', {'formset':formset})

URLS.py:

from django.urls import path
from . import views

    urlpatterns = [
        path ( 'str_dashboard/' , views.str_dashboard , name = 'str_dashboard' ) ,
        path ( 'application/' , views.startup, name = 'str_name' ) ,
        path ( 'application-1/' , views.team, name = 'str_team' ) ,
    ]

服务器会话:

     System check identified no issues (0 silenced).
     July 19, 2019 - 18:51:49
     Django version 2.1.8, using settings 'sourcing.settings'
     Starting development server at http://127.0.0.1:8000/
     Quit the server with CTRL-BREAK.
     [19/Jul/2019 18:51:53] "GET / HTTP/1.1" 200 718
     [19/Jul/2019 18:51:55] "GET /str_login/ HTTP/1.1" 200 2205
     [19/Jul/2019 18:52:02] "POST /str_login/ HTTP/1.1" 302 0
     [19/Jul/2019 18:52:02] "GET /str_dashboard/ HTTP/1.1" 200 11222
     [19/Jul/2019 18:52:05] "GET /application/ HTTP/1.1" 200 1464
     [19/Jul/2019 18:52:13] "POST /application/ HTTP/1.1" 302 0
     [19/Jul/2019 18:52:14] "GET /application-1/ HTTP/1.1" 200 4687
     Internal Server Error: /application-1/
     Traceback (most recent call last):
       File "C:\Users\Lenovo\venv\lib\site-                           packages\django\core\handlers\exception.py", line 34, in inner
         response = get_response(request)
       File "C:\Users\Lenovo\venv\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
         response = self.process_exception_by_middleware(e, request)
       File "C:\Users\Lenovo\venv\lib\site-         packages\django\core\handlers\base.py", line 124, in _get_response
         response = wrapped_callback(request, *callback_args,          **callback_kwargs)
       File          "C:\Users\Lenovo\PycharmProjects\untitled1\sourcing\startups\views.py", line 30,          in team
         if formset.is_valid():
       File "C:\Users\Lenovo\venv\lib\site-         packages\django\forms\formsets.py", line 301, in is_valid
         self.errors
       File "C:\Users\Lenovo\venv\lib\site-         packages\django\forms\formsets.py", line 281, in errors
         self.full_clean()
       File "C:\Users\Lenovo\venv\lib\site-         packages\django\forms\formsets.py", line 322, in full_clean
         for i in range(0, self.total_form_count()):
       File "C:\Users\Lenovo\venv\lib\site-         packages\django\forms\formsets.py", line 110, in total_form_count
         return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT],          self.absolute_max)
       File "C:\Users\Lenovo\venv\lib\site-         packages\django\utils\functional.py", line 37, in __get__
         res = instance.__dict__[self.name] = self.func(instance)
       File "C:\Users\Lenovo\venv\lib\site-         packages\django\forms\formsets.py", line 92, in management_form
         code='missing_management_form',
     django.core.exceptions.ValidationError: ['ManagementForm data is          missing or has been tampered with']
     [19/Jul/2019 18:52:36] "POST /application-1/ HTTP/1.1" 500 93454

2 个答案:

答案 0 :(得分:1)

非常感谢Farhani Walid,他的一切功劳归功于他,他帮助解决了这个问题,我在最终代码集下面发布了该代码集,以供将来遇到相同问题的其他人使用。请注意,在我的情况下,我不必导入会话,但在您的情况下,我建议这样做,以防您的IDE要求

server {
    listen 80;
    listen [::]:80 default_server;

    return 301 https://$host$request_uri;
}
server {
    # Enable HTTP/2
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name domain.com;

    # Use the Letā€™s Encrypt certificates
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

    # Include the SSL configuration from cipherli.st
    include snippets/ssl-params.conf;

    location /api {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://localhost:5000;
        proxy_ssl_session_reuse off;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
    }
    location / {
        root /var/www/html/Web/dist; // Vue dist folder
    }
}

forms.py:

     from django.contrib.sessions.models import Session

models.py:

    from .models import *
    from django import forms

    class StartupNameForm (forms.ModelForm):
       class Meta:
         model = Startup
         fields = ['startup_name',]

views.py:

     from django.db  import models

     class Startup (models.Model):
         startup_name=models.CharField('Startup Name', max_length = 100)


         def __str__(self) :
             return self.startup_name

     class Team (models.Model):
         name = models.CharField ( 'Name' , max_length = 100 )
         position = models.CharField ( 'Position' , max_length = 100 )
         startup = models.ForeignKey(Startup, on_delete = models.CASCADE)

         def __str__(self):
             return self.name

urls.py:

     from django.forms import modelformset_factory
     from .decorators import str_required
     from django.contrib.auth.decorators import login_required
     from django.shortcuts import render , redirect
     from .forms import *


     @login_required ( login_url = 'str_login' )
     @str_required
     def str_dashboard(request) :
         return render ( request , 'str_dashboard.html' )


     def startup(request):
         if request.method == 'POST':
            form = StartupNameForm(request.POST)
             if form.is_valid():
                 saved_startup_object = form.save()
                 request.session['saved_startup_object'] = saved_startup_object.id
                 return redirect('str_team')
         else:
             form = StartupNameForm()
             return render(request, 'application/str_name.html', {'form': form})

     def team(request):
         stored_startup_object = request.session['saved_startup_object']
         TeamFormset = modelformset_factory(Team, fields = ('name','position'), extra = 1)
         if request.method=='POST':
             formset = TeamFormset(request.POST)
             if formset.is_valid():
                 team_startup = None
             if stored_startup_object is not None:
                 team_startup = Startup.objects.get(id=stored_startup_object)
                 instances = formset.save(commit = False)
                 for instance in instances:
                     instance.startup = team_startup
                     instance.save()
             return redirect('str_dashboard')
         else:
             formset = TeamFormset ()
             return render(request,'application/str_team.html', {'formset':formset})

答案 1 :(得分:0)

如果我完全了解您要在此处执行的操作,则要将在第一个视图中创建的startup.id分配为在第二个视图中创建的团队模型的外键,在这种情况下,您可以想要将启动的值从第一个视图传递到第二个视图,并且为了做到这一点,我在那种情况下使用的是会话。 您将启动ID作为变量存储在会话中,并在第二个视图上对其进行解释,不要忘了像这样导入Session:

from django.contrib.sessions.models import Session

您可以从此处的文档获取有关会话的所有必需信息 https://docs.djangoproject.com/en/2.2/topics/http/sessions/

编辑:

尝试像这样更新您的视图,并在服务器日志中提供输出

def startup(request):
    if request.method == 'POST':
        form = StartupNameForm(request.POST)
        if form.is_valid():
            saved_startup_object = form.save()
            request.session['saved_startup_object'] = saved_startup_object.id
            return redirect('str_team')
    else:
        form = StartupNameForm()
        return render(request, 'application/str_name.html', {'form': form})

def team(request):
    stored_startup_object = request.session['saved_startup_object']
    TeamFormset = modelformset_factory(Team, fields = ('name','position'), extra = 1)
    if request.method=='POST':
        formset = TeamFormset(request.POST)
        if formset.is_valid():
        team_startup = None
        if stored_startup_object is not None:
            team_startup = Startup.objects.get(id=stored_startup_object)
            instances = formset.save(commit = False)
            for instance in instances:
                instance.Team.startup = team_startup
                instance.save()
        return redirect('str_dashboard')
    else:
        formset = TeamFormset ()
        return render(request,'application/str_team.html', {'formset':formset})