简体   繁体   English

在Django-Rest框架中使用模型

[英]Using Models in Django-Rest Framework

I am new to Django-Rest Framework and I wanted to develop API calls. 我是Django-Rest Framework的新手,我想开发API调用。 I am currently using Mysql database so if I have to make changes in the database, do I have to write models in my project or Can I execute the raw data operation onto my database. 我当前正在使用Mysql数据库,因此,如果必须在数据库中进行更改,是否必须在项目中编写模型,或者可以对数据库执行原始数据操作。

Like: This is my urls.py file which contains a list of URLs and if any of the URL is hit it directly calls to view function present in views.py file and rest I do the particular operation in that function, like connecting to MySQL database, executing SQL queries and returning JSON response to the front end. 就像:这是我的urls.py文件,其中包含URL列表,如果命中了任何URL,它会直接调用views.py文件中存在的view函数,其余的我将在该函数中执行特定操作,例如连接到MySQL数据库,执行SQL查询并将JSON响应返回到前端。

Is this a good approach to making API calls? 这是进行API调用的好方法吗? If not Please guide me. 如果没有,请指导我。

Any advice or help will be appreciated. 任何建议或帮助将不胜感激。

you don't need to use models, but you really should. 不需要使用模型,但是您确实应该使用模型。 django's ORM (the way it handles reading/writing to databases) functionality is fantastic and really useful. django的ORM(处理对数据库的读/写的方式)功能非常出色,而且非常有用。

if you're executing raw sql statements all the time, you either have a highly specific case where django's functions fail you, or you're using django inefficiently and should rethink why you're using django to begin with. 如果您一直在执行原始sql语句,则可能是django函数使您失败的情况非常特殊,或者您使用django的效率低下,应该重新考虑为什么要使用django。

Django REST Framework is designed to work with Django Framework. Django REST框架旨在与Django框架一起使用。 And Django ORM is an integral part of Django Framework. Django ORM是Django Framework的组成部分。 Granted, that it is possible to use Django and DRF without using ORM, but you will be basically fighting against the framework instead of using the framework to help you. 当然,可以在不使用ORM的情况下使用Django和DRF,但是您将基本上与该框架进行斗争,而不是使用该框架来帮助您。 So, you have three basic approaches. 因此,您有三种基本方法。

  1. If all you want is to develop RESTful APIs in python and pull data from an existing MySQL database or you don't have a database, but you want something simple. 如果您想要的是用python开发RESTful API并从现有的MySQL数据库中提取数据,或者您没有数据库,但是想要简单的东西。 You can use something framework agnostic, like restless ( http://restless.readthedocs.io/en/latest/ ) or even hug ( https://github.com/timothycrosley/hug ) 您可以使用与框架无关的东西,例如躁动( http://restless.readthedocs.io/en/latest/ )甚至拥抱( https://github.com/timothycrosley/hug

  2. If you do not have any existing data and you want a full blown web framework, you should consider using Django (I make my living as a Django dev, there is no shame in this) and embrace the ORM. 如果您没有任何现有数据,并且想要一个完善的Web框架,则应考虑使用Django(我以​​Django开发人员为生,这并不令人遗憾),并且欢迎使用ORM。 In this case, DRF is one of the better REST frameworks for Django at the moment. 在这种情况下,DRF是目前针对Django的更好的REST框架之一。

  3. If you have existing database and are somehow stuck with using Django, there are some ways to use Django ORM with existing data, you should look at Django docs on the topic ( https://docs.djangoproject.com/en/1.9/howto/legacy-databases/ ) 如果您拥有现有数据库并且以某种方式无法使用Django,则可以通过多种方式将Django ORM与现有数据结合使用,您应该查看有关该主题的Django文档( https://docs.djangoproject.com/zh/1.9/howto / legacy-databases /

Why would you use Django without hitting the database with the ORM? 为什么您要使用Django而不用ORM访问数据库? Most of the times the ORM works as you'd expect, and even allow you to perform searches like this: 在大多数情况下,ORM都可以按您期望的那样工作,甚至允许您执行以下搜索:

class Foo(models.Model):
    code = models.CharField(max_length=10, ...)

class Bar(models.Model):
    code = models.CharField(max_length=10, ...)
    foo = models.ForeignKey(Foo, ...)

And perform a query like this: 并执行如下查询:

Bar.objects.get(code='baz', foo_code='bat')

Which would be the same, but better, than: 与以下内容相同但更好:

select bar.* from yourapp_bar bar inner join yourapp_foo foo on (bar.foo_id = foo.id) where bar.code = 'baz' and foo.code = 'bat'

Shorter and more maintainable. 更短,更可维护。

Now, speaking about Django Rest Framework and Django in general: Although the latter modifications to both Django and DRF involve you cannot suddenly expect nested objects be created in the same moment the parent objects are (eg Foo is parent, while Bar is nested), as it happens in relation managers (Django) and create/update methods in the ModelSerializer class, you can still trust Django to save your time, effort, and life by using it instead of SQL. 现在,一般来说说Django Rest Framework和Django:尽管对Django和DRF的后一种修改都涉及到您不能突然期望在父对象同时创建嵌套对象(例如Foo是父对象,而Bar是嵌套的),尽管它发生在关系管理器(Django)和ModelSerializer类中的create / update方法中,但您仍然可以信任Django,而不是使用SQL来节省时间,精力和生命。

I will give you an example with DRF. 我将为您提供DRF的示例。 We will assume only Foo models are involved here. 我们将假定此处仅涉及Foo模型。 Which one would you prefer? 您想要哪一个?

# yourapp.urls
from .views import UserViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'users', UserViewSet)
urlpatterns = router.urls

# yourapp.views
class FooViewSet(viewsets.ModelViewSet):
    """
    A viewset that provides the standard actions for
      a single foo element
    """
    queryset = Foo.objects.all()
    serializer_class = FooSerializer
    # I am assuming you created the FooSerializer to map certain fields...

or ... 要么 ...

# yourapp.urls
from .views import mywholeurl
from django.conf.urls import url

urlpatterns = [
    url('users/(\d+)', mywholeview),
]

# yourapp.views

from django.db import connection
from rest_framework import status
from rest_framework.response import Response

def mywholeview(request, id):
    cursor = connection.cursor()
    if request.method in ('POST', 'PUT'):
        cursor.execute('update yourapp_foo set %s where id = %%s' % ', '.join(["%s=%%s" % p[0] for p in request.data.items()]), list(p[1] for p in request.data.items()) + [id])
        row = cursor.fetchone()
        if row[0]
            return Response(status=status.HTTP_201_ACCEPTED)
        else:
            return Response(status=status.HTTP_404_NOT_FOUND)
    elif request.method = 'GET':
        cursor.execute('select * from yourapp_foo where id = %s', [id])
        row = cursor.fetchone()
        if row:
            columns = [col[0] for col in cursor.description]
            data = zip(columns, row)
            return Response(data, status=status.HTTP_200_OK)
        else:
            return Response(status=status.HTTP_404_NOT_FOUND)
    elif request.method = 'DELETE':
        cursor.execute('delete from yourapp_foo where id = %s', [id])
        row = cursor.fetchone()
        if not int(row[0]):
            return Response(status=status.HTTP_404_NOT_FOUND)
        else:
            return Response(status=status.HTTP_204_NO_CONTENT)

the latter code is untested and only serves for teoretical purpose. 后者的代码未经测试,仅用于理论上的目的。 it is pretty insecure and not intended to be executed in production since it is a bad idea 这是非常不安全的,并且不打算在生产中执行,因为这是一个坏主意

I would prefer with the shortest approach. 我希望使用最短的方法。

My conclusion is: learn the ORM! 我的结论是:学习ORM! If you need to respect your database because it is preexisting, you could use managed models. 如果由于数据库已存在而需要尊重数据库,则可以使用managed模型。 But always... use the ORM and the features given to you by both Django and DRF. 但始终...使用Django和DRF提供的ORM和功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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