更改模型视图集中的数据

restframework-datachange的Python项目详细描述


restframewramewatachange是rest_框架的一个增强。要使用它,我们必须对django和rest_框架有基本的理解。

一。安装

像往常一样,使用pip:

$ pip install restframework_datachange
$ pip install django
$ pip install djangorestframework

2.在使用restframework_datachange之前

我们制作了一个示例restframework支持项目。

$ django-admin startproject my_project
my_project$ cd my_project
my_project$ django-admin startapp movie

现在我们按如下方式编写文件:

制作模型。

my_project/movie/models.py

fromdjango.dbimportmodelsclassCast(models.Model):SEX_CHOICE=((1,"Male"),(2,"Female"))sex=models.IntegerField(choices=SEX_CHOICE,default=1)profession=models.CharField(max_length=100,default="")foreign_name=models.CharField(max_length=100,default="")def__str__(self):returnself.foreign_nameclassOneMovie(models.Model):COUNTRY_CHOICE=((1,"UK"),(2,"US"))name=models.CharField(max_length=200,default="")director=models.ManyToManyField(Cast,related_name="director")actors=models.ManyToManyField(Cast,related_name="actors")country=models.IntegerField(default="",choices=COUNTRY_CHOICE)def__str__(self):returnself.name

生成序列化程序。有关SlugRelatedField的用法,请参阅the document of djangorestframework

my_project/movie/serializers.py

fromrest_framework.serializersimportModelSerializer,SlugRelatedFieldfrommovie.modelsimportOneMovie,CastclassMovieSerializer(ModelSerializer):director=SlugRelatedField(slug_field="foreign_name",queryset=Cast.objects.all(),many=True)actors=SlugRelatedField(slug_field="foreign_name",queryset=Cast.objects.all(),many=True)classMeta:model=OneMoviefields="__all__"

查看

my_project/movie/views.py

fromdjango.shortcutsimportrenderfromrest_framework.viewsetsimportModelViewSetfrommovie.modelsimportOneMoviefrommovie.serializersimportMovieSerializerclassMovieViewSet(ModelViewSet):queryset=OneMovie.objects.all()serializer_class=MovieSerializer

更改设置

我的项目/我的项目/设置.py

...INSTALLED_APPS=["django.contrib.admin","django.contrib.auth","django.contrib.contenttypes","django.contrib.sessions","django.contrib.messages","django.contrib.staticfiles","rest_framework",#"movie"#]...

进行迁移和迁移。

my_project/my_project $ cd ..
my_project $ python manage.py makemigrations
Migrations for 'movie':
  movie/migrations/0001_initial.py
    - Create model Cast
    - Create model OneMovie

my_project$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, movie, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying movie.0001_initial... OK
  Applying sessions.0001_initial... OK

为整个项目创建URL。

my_project/my_project/url.py

fromdjango.contribimportadminfromdjango.urlsimportpathfromrest_frameworkimportroutersfrommovie.viewsimportMovieViewSeturlpatterns=[path("admin/",admin.site.urls),]router=routers.DefaultRouter()router.register(r"movie",MovieViewSet,base_name="movie")urlpatterns+=router.urls

现在我们为数据库创建一些数据。

my_project$pythonmanage.pyshellIn[1]:frommovie.modelsimportOneMovieIn[2]:frommovie.modelsimportCastIn[3]:daniel=Cast.objects.create(sex=1,profession="actor",foreign_name="Daniel")In[4]:danielOut[4]:<Cast:Daniel>In[5]:emma=Cast.objects.create(sex=2,profession="actor",foreign_name="Emma")In[6]:Cast.objects.all()Out[6]:<QuerySet[<Cast:Daniel>,<Cast:Emma>]>In[7]:david=Cast.objects.create(sex=1,profession="director",foreign_name="David")In[8]:harry_potter_movie=OneMovie.objects.create(name="Harry Potter and the Goblet of Fire",country=2)In[9]:harry_potter_movie.director.add(david)In[10]:harry_potter_movie.actors.add(daniel)In[11]:harry_potter_movie.actors.add(emma)In[12]:harry_potter_movie.save()In[13]:harry_potter_movieOut[13]:<OneMovie:HarryPotterandtheGobletofFire>In[14]:harry_potter_movie.director.all()Out[14]:<QuerySet[<Cast:David>]>In[15]:harry_potter_movie.actors.all()Out[16]:<QuerySet[<Cast:Daniel>,<Cast:Emma>]>In[16]:exit()

现在我们运行服务器。

my_project $ python manage.py runserver 0.0.0.0:8000

启动浏览器并输入http://127.0.0.1:8000/,单击"movie": "http://127.0.0.1:8000/movie/"

塔达!一切看起来都很完美。下面是你将看到的。

[
    {
        "id": 1,
        "director": [
            "David"
        ],
        "actors": [
            "Daniel",
            "Emma"
        ],
        "name": "Harry Potter and the Goblet of Fire",
        "country": 2
    }
]

三。更改数据

我们只希望电影"name""Harry",而不是"Harry Potter and the Goblet of File"。也就是说,我们要更改返回的数据。这时restframework_datachange出现了!

my_project/movie/views.py

fromrestframework_datachange.viewsetsimportRModelViewSet# frommovie.modelsimportOneMoviefrommovie.serializersimportMovieSerializerclassMovieAdjust(object):# defchange_name(self,value):# xx = namereturnvalue.split(" ")[0]# classMovieViewSet(MovieAdjust,RModelViewSet):# queryset=OneMovie.objects.all()serializer_class=MovieSerializer

通过向Adjust对象添加change_xx,并将继承更改为RModelViewSet,我们将返回的"name"字段的值从"Harry Potter and the Goblet of File"更改为"Harry"

[
    {
        "id": 1,
        "director": [
            "David"
        ],
        "actors": [
            "Daniel",
            "Emma"
        ],
        "name": "Harry",
        "country": 2
    }
]

现在我们将"country"代码更改为相应的国家名称:

my_project/movie/views.py

...classMovieAdjust(object):defchange_name(self,value):returnvalue.split(" ")[0]defchange_country(self,value):dic={1:"UK",2:"US"}returndic[value]...

塔达!

[
    {
        "id": 1,
        "director": [
            "David"
        ],
        "actors": [
            "Daniel",
            "Emma"
        ],
        "name": "Harry",
        "country": "US"  
    }
]

四。基于一个字段添加新数据

我们需要一个基于数据原始字段的新字段。例如,我们希望"actors"的字符串版本命名为"string_actors"

my_project/movie/views.py

...classMovieAdjust(object):string_actors_src1="actors"defchange_name(self,value):returnvalue.split(" ")[0]defchange_country(self,value):dic={1:"UK",2:"US"}returndic[value]defadd_string_actors(self,value):return", ".join(value)...

生成一个add_xx方法,传递一个value并对其进行修改,然后将源字段指定为xx_src1。然后你就可以看到这个了。

[
    {
        "id": 1,
        "director": [
            "David"
        ],
        "actors": [
            "Daniel",
            "Emma"
        ],
        "name": "Harry",
        "country": "US",
        "string_actors": "Daniel, Emma"
    }
]

四。基于两个或多个字段添加新数据

假设我们想将"country"字段和"name"字段连接起来形成"detail"字段。

classMovieAdjust(object):string_actors_src1="actors"detail_src1="country"# xx = detaildetail_src2="name"# xx = detaildefchange_name(self,value):returnvalue.split(" ")[0]defchange_country(self,value):dic={1:"UK",2:"US"}returndic[value]defadd_string_actors(self,value):return", ".join(value)defadd_detail(self,*value):# xx = detailreturn", ".join([str(i)foriinvalue])

现在您可以看到:

[
    {
        "id": 1,
        "director": [
            "David"
        ],
        "actors": [
            "Daniel",
            "Emma"
        ],
        "name": "Harry",
        "country": "US",
        "detail": "2, Harry Potter and the Goblet of Fire",
        "string_actors": "Daniel, Emma"
    }
]

注意"detail"中的"country"部分,它是原始值2,而不是修改值"US"。这里,"detail"有源字段"country""name",所以value[0]"country"字段的值,2。而value[1]"name""Harry Potter and the Goblet of Fire"的值。

您也可以这样编写代码:

classMovieAdjust(object):string_actors_src1="actors"detail_src1="country"detail_src2="name"defchange_name(self,value):returnvalue.split(" ")[0]defchange_country(self,value):dic={1:"UK",2:"US"}returndic[value]defadd_string_actors(self,value):return", ".join(value)defadd_detail(self,country,name):returnstr(country)+", "+str(name)

确保self旁边参数的数目和位置与新创建字段的src相同。

5个。干预其他行为。

如果您碰巧知道restframework的retrievecreateupdate操作,您可以通过基于下表创建Adjust对象来干预您的返回:

ActionsModificationMethod PrefixSource Field Suffix
listadd a fieldaddsrc
listchange a fieldchange--
retrieveadd a fieldappendorg
retrievechange a fieldmodify--
createadd a fieldattachbir
createchange a fieldreform--
updateadd a fieldadjoinlch
updatechange a fieldvary--

例如:

http://127.0.0.1:8000/movie/1/调用retrieve方法。

classMovieAdjust(object):string_actors_src1="actors"detail_src1="country"# xx = detail(list)detail_src2="name"# xx = detail(list)string_actors_retrieve_org1="actors"# yy = string_actors_retrieve(retrieve)defchange_name(self,value):returnvalue.split(" ")[0]defchange_country(self,value):dic={1:"UK",2:"US"}returndic[value]defadd_string_actors(self,value):return", ".join(value)defadd_detail(self,*value):# xx = detailreturn", ".join([str(i)foriinvalue])defmodify_country(self,value):dic={1:"United Kingdom",2:"United States"}returndic[value]defappend_string_actors_retrieve(self,value):# yy = string_actors_retrievereturn", ".join(value)
{
    "id": 1,
    "director": [
        "David"
    ],
    "actors": [
        "Daniel",
        "Emma"
    ],
    "name": "Harry Potter and the Goblet of Fire",
    "country": "United States",
    "string_actors_retrieve": "Daniel, Emma"
}

6.显示/隐藏字段

如果要显示或隐藏字段,可以修改操作特定的_fields_exclude属性。

classMovieAdjust(object):list_exclude=["actors"]

会让您:

[
    {
        "id": 1,
        "director": [
            "David"
        ],
        "name": "Harry Potter and the Goblet of Fire",
        "country": 2
    }
]
classMovieAdjust(object):list_fields=["actors","name"]

会让您:

[
    {
        "actors": [
            "Daniel",
            "Emma"
        ],
        "name": "Harry Potter and the Goblet of Fire"
    }
]

7号。将python dict转换为模型

如果您有一个python dict并希望将其转换为django模型,那么可以使用modelmaker

model_maker(dic,file='fake_model.py',class_name='Default',name_changer=camel_to_,default_settings=None,**config)

dic:Pythondic。

file:模型将写入指定的文件。作为""传递,它将只返回打印版本。

class_name:型号。

name_changer:将某个字符串更改为另一个字符串的方法。默认值是一个函数,它将驼峰大小写转换为下划线。

default_settings:指定字段类型的默认属性设置的python dict。

config:设置模型的属性。详情请参阅the documents of django

示例:

fromrestframework_datachange.model_makerimportmodel_makerfromdatetimeimportdatetimedic={"apple":1,# IntegerField"boy":1.2,# FloatField"cat":"string",# CharField"dog":[{"json":1}],# JSONField"elephant":datetime.now(),# DatetimeField"changed":"string"}config={"apple__choices":[(1,"UK"),(2,"US")],"boy__null":True,"cat__max_length":20,"dog__verbose_name":"Dog","elephant__auto_now":True}defname_changer(string):li=["apple","boy","cat","dog","elephant"]ifstringnotinli:return"fog"returnstringprint(model_maker(dic,file="",class_name="M",name_changer=name_changer,**config))

会给你你:

fromdjango.contrib.postgres.fieldsimportJSONFieldfromdjango.dbimportmodelsclassM(models.Model):apple=models.IntegerField(verbose_name="",help_text="",null=True,choices=[(1,"UK"),(2,"US")])boy=models.FloatField(verbose_name="",help_text="",null=True)cat=models.CharField(verbose_name="",help_text="",default="",max_length=20)dog=JSONField(verbose_name="Dog",help_text="",null=True,blank=True)elephant=models.DateTimeField(verbose_name="",help_text="",auto_now=True,auto_now_add=False)fog=models.CharField(verbose_name="",help_text="",default="",max_length=64)

通过向default_settings参数传递python dict,可以更改model_maker的默认设置。

dic={"apple":1}# IntegerFieldprint(model_maker(dic,file="",class_name="AppleCart",default_settings={"int":{"null":True}}))

会给你:

fromdjango.dbimportmodelsclassAppleCart(models.Model):apple=models.IntegerField(null=True)

不同类型的默认设置如下:

{"int":{"verbose_name":"","help_text":"","null":True},"str":{"verbose_name":"","help_text":"","default":"","max_length":64},"datetime":{"verbose_name":"","help_text":"","auto_now":False,"auto_now_add":False},"date":{"verbose_name":"","help_text":"","auto_now":False,"auto_now_add":False},"json":{"verbose_name":"","help_text":"","null":True,"blank":True},"bool":{"verbose_name":"","help_text":"","null":True},"float":{"verbose_name":"","help_text":"","null":True}}

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
Android中Twitter共享的java xAuth身份验证?   带有@XmlAnyAttribute和方法的java Bug?(使用JAXB-RI)   安卓 ArrayAdapter导致java。lang.NullPointerException   java如何使用JExel从现有excel文件中删除工作表   java树映射随机停止正确返回值   使用switch和scanner类java使用用户选择   java JCalendar多天选择   Java文件zip正在创建损坏的文件   Ajax调用中的java未定义错误   java处理JSON更改信息的最佳方法   java JNI不适用于AppKit线程   java在运行时为JTable的特定行设置背景色   java如何在for循环中添加按钮?   java在getclass()方法之后强制转换对象