简体   繁体   中英

Django - NOT NULL constraint failed

I'm currently working on a Django app that will parse the contents of an uploaded log file to the associated database in my Django project. I've managed to get it all running as expected except it won't associate my uploaded data with the model's ForeignKey. I can assign null=True which resolves the integrity error but then of course, it doesn't assign any of the uploaded data to that ForeignKey. Here's the code:

models.py

class Case(models.Model):

    case_ref = models.CharField(max_length=8)
    oic = models.CharField(max_length=50)
    subject = models.CharField(max_length=100)
    submitted_date = models.DateTimeField(default=datetime.now, blank=True)

    def get_absolute_url(self):
        return reverse('case_list', kwargs={'pk': self.pk})

    def __str__(self):
        return self.case_ref + " " + self.subject
    
class TeamviewerLogs(models.Model):
    
        case = models.ForeignKey(Case, on_delete=models.DO_NOTHING) 
        teamviewer_id = models.IntegerField()
        teamviewer_name = models.TextField()
        connection_start = models.TextField()
        connection_end = models.TextField()
        local_user = models.TextField()
        connection_type = models.TextField()
        unique_id = models.TextField()
    
        def get_absolute_url(self):
            return reverse('case_list', kwargs={'pk': self.pk})
    
        def __str__(self):
            return str(self.teamviewer_id) + " - " + str(self.teamviewer_id)

forms.py

class UploadLog(forms.ModelForm):
    file = forms.FileField()
    
    class Meta:
      model = TeamviewerLogs
      fields = [
        'file'
      ]

views.py

def add_logs(request, pk):
  case = get_object_or_404(Case, pk=pk)

  if request.method == 'POST':
      form = UploadLog(request.POST, request.FILES)
      
      if form.is_valid():
          teamviewer = form.save(commit=False)
          teamviewer.case = case


          log_file = request.FILES['file']
          log_file = filter(None, (line.rstrip() for line in log_file))

          for lines in log_file:

              split = lines.decode('utf-8').split('\t')

              teamviewer_id = split[0]
              teamviewer_name = split[1]
              connection_start = split[2]
              connection_end = split[3]
              local_user = split[4]
              connection_type = split[5]
              unique_id = split[6]
          


              teamviewer = TeamviewerLogs(teamviewer_id=teamviewer_id, teamviewer_name=teamviewer_name, 
                                        connection_start=connection_start, connection_end=connection_end, 
                                        local_user=local_user, connection_type=connection_type, unique_id=unique_id)

              teamviewer.save()
              return redirect('tv_log_details', pk=case.pk)
      form.save()

  else:
      form = UploadLog()

  return render(request, 'teamviewer/add_logs.html', {'form': form})

But when I click to upload the file I'm hit with: 在此处输入图片说明

When it tries to execute teamviewer.save().

I've been trying to resolve this issue for hours and have tried so many different variations of answers from Stackoverflow or previous code I've used that has worked for different models but I've hit a brick wall...hard!

Any help anyone can offer would be greatly appreciated.

Ok, so here's an example of the concept I've suggested in the comments.

I've got a view which passes some data to the a form;

class ListingDetailView(DetailView):
    """ Listing detail page """
    model = Listing
    template_name = 'listing.html'

    def get_form_kwargs(self):
        """Return the kwargs for the form"""
        kwargs = {}
        initial = {
            'listing': self.object,
        }

        kwargs['initial'] = initial
        return kwargs

    def get_form(self):
        form = ApplicationSignupForm(
            **self.get_form_kwargs()
        )
        return form

    def get_context_data(self, **kwargs):
        """ Add our form to the context """
        context = super().get_context_data(**kwargs)
        context['form'] = self.get_form()
        return context

The form then makes use of that initial data and sets the field it relates to as hidden. I don't validate this data, but I'll try to show how you might do that;

class ApplicationSignupForm(forms.ModelForm):


    class Meta:
        """ Setup the form """
        fields = (
            'listing',
            ...
        )
        model = Application
        widgets = {
            'listing': forms.HiddenInput()
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        initial_data = kwargs['initial']
        self.listing = initial_data.get('listing')
        

    def clean(self):
        """
        Custom form cleaning
        """
        cleaned_data = super().clean()

        listing = cleaned_data.get('listing')
        if listing != self.listing:
            self.add_error('listing', "You can't modify this value")

        return cleaned_data

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM