当前位置: 首页 > 面试题库 >

轻松访问Django模型:定义Django项目的路径

谷弘致
2023-03-14
问题内容

我是Python和Django的新手。我目前正在探索使用Scrapy抓取网站并将数据保存到Django数据库。我的目标是根据用户提供的域来运行蜘蛛。

我写了一个Spider来提取我需要的数据,并在调用时将其正确存储在json文件中

scrapy crawl spider -o items.json -t json

如刮板教程中所述。

我现在的目标是使Spider成功地将数据保存到Django数据库,然后根据用户输入来使Spider运行。

我知道与此主题相关的帖子很多,例如:
链接 链接

但是,花了超过8个小时的时间试图使它工作,我假设我不是唯一仍然面临此问题的人。为此,我将尝试收集到目前为止我在本文中获得的所有知识,并希望在以后发布可行的解决方案。因此,这篇文章相当长。

在我看来,有两种不同的解决方案可以将数据从Scrapy保存到Django数据库。一种是使用DjangoItem,另一种是直接导入模型)。

我并没有完全意识到这两者的优缺点,但是似乎区别只是使用DjangoItem更方便,更短。

我做了什么:

我已经添加:

def setup_django_env(path):
    import imp, os
    from django.core.management import setup_environ

    f, filename, desc = imp.find_module('settings', [path])
    project = imp.load_module('settings', f, filename, desc)

    setup_environ(project)

setup_django_env('/Users/Anders/DjangoTraining/wsgi/')

我得到的错误是:

ImportError: No module named settings

我以为我在以错误的方式定义Django项目的路径?

我也尝试了以下方法

setup_django_env('../../')

如何正确定义Django项目的路径?(如果这是问题)


问题答案:

我认为主要的误解是软件包路径与设置模块路径。为了从外部脚本使用django的模型,您需要设置DJANGO_SETTINGS_MODULE。然后,该模块必须是
可导入的 (即,如果设置路径为myproject.settings,则该语句from myproject import settings应在python shell中运行)。

由于django中的大多数项目都是在default之外的路径中创建的PYTHONPATH,因此必须将项目的路径添加到PYTHONPATH环境变量中。

这是一个分步指南,用于将完全正常(且最少)的Django模型集成到Scrapy项目中:

注意: 本说明在上次编辑日期生效。如果对您不起作用,请添加评论并描述您的问题以及scrapy / django版本。

  1. 项目将在/home/rolando/projects目录中创建。

  2. 启动 django项目

    $ cd ~/projects
    

    $ django-admin startproject myweb
    $ cd myweb
    $ ./manage.py startapp myapp

  3. 在中创建模型myapp/models.py

    from django.db import models
    

    class Person(models.Model):
    name = models.CharField(max_length=32)

  4. 添加myappINSTALLED_APPSmyweb/settings.py

    # at the end of settings.py
    

    INSTALLED_APPS += (‘myapp’,)

  5. 在中设置我的数据库设置myweb/settings.py

    # at the end of settings.py
    

    DATABASES[‘default’][‘ENGINE’] = ‘django.db.backends.sqlite3’
    DATABASES[‘default’][‘NAME’] = ‘/tmp/myweb.db’

  6. 创建数据库。

    $ ./manage.py syncdb --noinput
    

    Creating tables …
    Installing custom SQL …
    Installing indexes …
    Installed 0 object(s) from 0 fixture(s)

  7. 创建 scrapy项目

    $ cd ~/projects
    

    $ scrapy startproject mybot
    $ cd mybot

  8. 在中创建一个项目mybot/items.py

注意: 在较新版本的Scrapy中,您需要安装scrapy_djangoitem和使用from scrapy_djangoitem import DjangoItem

    from scrapy.contrib.djangoitem import DjangoItem
    from scrapy.item import Field

    from myapp.models import Person


    class PersonItem(DjangoItem):
        # fields for this item are automatically created from the django model
        django_model = Person

最终的目录结构是这样的:

/home/rolando/projects
├── mybot
│   ├── mybot
│   │   ├── __init__.py
│   │   ├── items.py
│   │   ├── pipelines.py
│   │   ├── settings.py
│   │   └── spiders
│   │       └── __init__.py
│   └── scrapy.cfg
└── myweb
    ├── manage.py
    ├── myapp
    │   ├── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    └── myweb
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

从这里开始,基本上我们已经完成了在一个沙哑的项目中使用django模型所需的代码。我们可以使用scrapy shell命令立即对其进行测试,但是请注意所需的环境变量:

$ cd ~/projects/mybot
$ PYTHONPATH=~/projects/myweb DJANGO_SETTINGS_MODULE=myweb.settings scrapy shell

# ... scrapy banner, debug messages, python banner, etc.

In [1]: from mybot.items import PersonItem

In [2]: i = PersonItem(name='rolando')

In [3]: i.save()
Out[3]: <Person: Person object>

In [4]: PersonItem.django_model.objects.get(name='rolando')
Out[4]: <Person: Person object>

因此,它按预期工作。

最后,您可能不需要每次运行机器人时都必须设置环境变量。尽管最好的办法是将项目的程序包实际安装在中设置的路径中,但有许多替代方法可以解决此问题PYTHONPATH

这是最简单的解决方案之一:将这些行添加到mybot/settings.py文件中以设置环境变量。

# Setting up django's project full path.
import sys
sys.path.insert(0, '/home/rolando/projects/myweb')

# Setting up django's settings module name.
# This module is located at /home/rolando/projects/myweb/myweb/settings.py.
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'myweb.settings'

# Since Django 1.7, setup() call is required to populate the apps registry.
import django; django.setup()

注意: 更好的方法是在两个项目中都有setuptools基于setup.py文件的文件并运行python setup.py develop,这些文件会将您的项目路径链接到python的路径中(我假设您使用virtualenv)。

足够了。为了完整起见,这是一个可以正常工作的项目的基本介绍和管道:

  1. 创建蜘蛛。
    $ cd ~/projects/mybot
    

    $ scrapy genspider -t basic example example.com

蜘蛛代码:

    # file: mybot/spiders/example.py
from scrapy.spider import BaseSpider
from mybot.items import PersonItem


class ExampleSpider(BaseSpider):
    name = "example"
    allowed_domains = ["example.com"]
    start_urls = ['http://www.example.com/']

    def parse(self, response):
        # do stuff
        return PersonItem(name='rolando')
  1. 创建一个管道mybot/pipelines.py以保存该项目。
    class MybotPipeline(object):
    def process_item(self, item, spider):
        item.save()
        return item
    

item.save()如果您使用的是DjangoItem类,则可以在这里使用,也可以直接导入django模型并手动创建对象。两种方式的主要问题是定义环境变量,以便您可以使用django模型。

  1. 将管道设置添加到您的mybot/settings.py文件。

    ITEM_PIPELINES = {
    'mybot.pipelines.MybotPipeline': 1000,
    

    }

  2. 跑蜘蛛。

    $ scrapy crawl example
    


 类似资料:
  • 问题内容: 是否可以在Scrapy管道中访问django模型,以便将已抓取的数据直接保存到模型中? 我已经看到了,但是我真的不知道如何设置它吗? 问题答案: 如果还有其他人遇到相同的问题,这就是我解决的方法。 我将其添加到我的scrapy settings.py文件中: 注意:上面的路径是到你的django项目文件夹,而不是settings.py文件。 现在,你将可以在scrapy项目中完全访问d

  • 问题内容: 我在中的代码: 在“ settings.py”中: 但我得到一个错误: 问题答案: 在该范围内不是变量。你必须首先从上下文中获取它。传递t给装饰器并添加context到tag参数。 像这样:

  • 问题内容: 我在网上商店应用程序中有一个Orders模型,它具有一个自动递增的主键和一个自身的外键,因为可以将订单分为多个订单,但是必须保持与原始订单的关系。 我已经为管理站点注册了OrderAdmin类。对于详细视图,我已包含在属性中。当然,默认情况下,这会在选择框中列出所有订单,但这不是所需的行为。相反,对于没有父订单的订单(即未与其他订单拆分;为NULL /无)的订单不应该显示。对于已拆分的

  • 问题内容: 我有一个Scrapy项目,正在尝试将输出项保存为Django模型定义中的对象(我不使用DjangoItem)。 我正在按此处指定的方式导入Django设置。 在我的Scrapy项目中,我有一个管道类,该类最终处理所有项目并将其保存到数据库中: 但是,发生了一些奇怪的事情,对于第一个项目,我得到了一个错误(请参阅下文)。对于其余项目,一切都很好。假设我要保存7个项目,因此我在第一个保存错

  • 本文向大家介绍Django实现的自定义访问日志模块示例,包括了Django实现的自定义访问日志模块示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Django实现的自定义访问日志模块。分享给大家供大家参考,具体如下: 在Django默认没有访问日志模块,但是我们可以通过Django的Middleware来实现一个自己的访问日志模块。 首先在Django的工程下创建一个middlewar

  • 问题内容: 我有一个带有开始和结束日期范围的Django模型。我想强制执行验证,以便没有两个记录具有重叠的日期范围。最简单的实现方式是什么,这样我就不必重复编写逻辑了? 例如,我不想在Form 和 a 以及 admin表单中重新实现此逻辑, 并且 模型被重写。 据我所知,Django在全球范围内强制执行这些类型的条件并不容易。 Googling并不是很有帮助,因为“模型验证”通常是指验证特定的模型