如何解决此错误? TypeError:“ NoneType”对象不可调用

时间:2018-12-19 10:11:00

标签: django python-3.x python-2.7 django-models django-views

我正在尝试以编程方式创建一堆数据库对象,并使用以下代码将其自动保存到数据库中。但是由于某种原因,当我尝试保存对象(即投标对象)时,出现以下错误。在save_tender_to_db()函数中,触发错误的行是bid_obj.save()。是什么引起了这个问题?

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 353, in execute
    output = self.handle(*args, **options)
  File "C:\PROJECTS\leadshub\tender_matching_engine\management\commands\scrap_etenders.py", line 8, in handle
    main()
  File "C:\PROJECTS\leadshub\Tender_Loader\etenders_scraper.py", line 52, in main
    save_tender_to_db(entry)
  File "C:\PROJECTS\leadshub\Tender_Loader\etenders_scraper.py", line 129, in save_tender_to_db
    description=container_tag[0]
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 413, in create
    obj.save(force_insert=True, using=self.db)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 718, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 748, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 831, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 869, in _do_insert
    using=using, raw=raw)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 1136, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1288, in execute_sql
    for sql, params in self.as_sql():
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1241, in as_sql
    for obj in self.query.objs
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1241, in <listcomp>
    for obj in self.query.objs
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1240, in <listcomp>
    [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
  File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1168, in prepare_value
    value = value.resolve_expression(self.query, allow_joins=False, for_save=True)
TypeError: 'NoneType' object is not callable

请在下面查看我的代码。

#This is the model that stores the tender.
class Tender(models.Model):
    tenderCategory = models.ManyToManyField(Category, blank=False)       #this field holds the tender category, e.g. construction, engineering, human resources etc.
    tenderProvince = models.ManyToManyField(Province, blank=False)       #this is the province the tender was advertised from.
    buyersName = models.CharField(max_length=100)   #this is the name of the Buyer e.g. Dept. of Transport, Transnet, Dept of Agriculture etc.
    summary = models.TextField(blank=False)      #this is the tender title as per the Buyer.
    refNum = models.CharField(max_length=100)    #tender ref number as per the Buyer.
    issueDate = models.DateTimeField(blank=True, null=True)     #date the tender was published
    closingDate = models.DateTimeField(default=timezone.now, blank=True, null=True)   #tender closing date
    siteInspectionDate = models.DateTimeField(blank=True, null=True)
    siteInspection = RichTextField(blank=True, null=True)     #site inspection date, if any
    enquiries = RichTextField(blank=True, null=True) #this field stores details of the contact person, for the tender.
    description = RichTextField(blank=True, null=True)   #this is the body of the tender. the tender details are captured here.
    assigned_keywords = models.ManyToManyField(Keywords, blank=True)
    matched = models.BooleanField(default=False, blank=False)
    capture_date = models.DateField(default=timezone.now, blank=False, null=False)
    date_assigned = models.DateField(blank=True, null=True)
    tDocLinks = RichTextField(blank=True)

    def check_if_expired(self):
        if self.closingDate < timezone.now():
            return True
        else:
            return False

    class Meta:
        ordering = ['-closingDate']
def save_tender_to_db(data_rec_str):
    try:
        url_data_ls = data_rec_str.split(';')
        sauce_2 = urllib.request.urlopen('http://www.etenders.gov.za{}'.format(url_data_ls[0]))
        soup_2 = BeautifulSoup(sauce_2, 'html.parser')

        # finds the container div in the html.
        container_tag = soup_2.findAll('div', {'class': 'fieldset-wrapper'})

        if len(container_tag) == 1:
            tender_obj = Tender(
                # tenderCategory=Category.objects.get(pk=1),
                # tenderProvince=Province.objects.get(pk=1),
                summary=url_data_ls[5].strip(),
                refNum=url_data_ls[1].strip(),
                issueDate=extract_date(url_data_ls[3].strip(), 2),
                description=container_tag[0],
                matched=False,
                capture_date=timezone.now
            )
            tender_obj.save()  #this is the line that triggers the error

        else:
            tender_obj = Tender(
                # tenderCategory=Category.objects.get(pk=1),
                # tenderProvince=Province.objects.get(pk=1),
                summary=url_data_ls[5].strip(),
                refNum=url_data_ls[1].strip(),
                issueDate=extract_date(url_data_ls[2].strip(), 1),
                closingDate=extract_date(url_data_ls[3], 2),
                siteInspectionDate=extract_date(url_data_ls[4], 2),
                description=container_tag[0],
                tDocLinks = container_tag[1],
                matched=False,
                capture_date=timezone.now
            )
            tender_obj.save()    #this is the line that triggers the error


    except urllib.error.URLError as e:
        print(e)

最后,当我取消注释以下两行时,我得到了随后的错误。我该怎么解决?

 # tenderCategory=Category.objects.get(pk=1),
 # tenderProvince=Province.objects.get(pk=1),
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use tenderCategory.set() instead.

0 个答案:

没有答案