如何通过串行化器中的Django模型中的主键的价值来更改主键的价值?

发布于 2025-02-12 06:09:53 字数 1810 浏览 2 评论 0原文

是否有可能通过序列化器手动更改Autofield(主键)中的ID值?
我在django的文档中找到了这一点: https://docs.djangoproject.com/en/4.0/ref/models/instances/#auto-incrementing-primary-keys ,但我不知道该如何做到这一点。

我的任务是:如果没有给定ID的汽车不存在,请从外部API中获取汽车并保存。

模型:

from django.db import models

class Car(models.Model):
    speed = models.IntegerField(default=1)
    color = models.CharField(max_length=200)
    wheels = models.CharField(max_length=500)

我的序列化器:

from rest_framework import serializers
from .models import Car


class CarSerializer(serializers.ModelSerializer):
    class Meta:
        model = Car
        fields = ['id', 'speed', 'color', 'wheels']

我的视图:

@api_view(['GET', 'PUT', 'DELETE'])
def car_detail_id(request, id):
    try:
        car = Car.objects.get(pk=id)
    except Car.DoesNotExist:
        #-----------------------------------------------------------#
        car = search_car(id) #fetch car from external API
        if request.method == "GET" and car is not None:
            serializer = CarSerializer(data=car)
            if serializer.is_valid():
                serializer.save()
                return Response(status=status.HTTP_201_CREATED)
        #-----------------------------------------------------------#
        return Response(status=status.HTTP_404_NOT_FOUND)
    return car_detail(request, "id", car) #method to handle CRUD

汽车结构:

 {
    "speed": 1,
    "id": 1,
    "color": "Green",
    "wheels": "Black"
  },

此实现带有API给定ID的车辆,然后保存它,但具有不同的ID。 有什么更好的方法吗?在下面让我知道!

Is it somehow possible to manually change ID value in AutoField (primary key) through serializer?
I found this in documentation of Django: https://docs.djangoproject.com/en/4.0/ref/models/instances/#auto-incrementing-primary-keys, but I have no idea how to do this including serializers.

My task is: If car with given ID does not exists, fetch car from external API and save it.

Model:

from django.db import models

class Car(models.Model):
    speed = models.IntegerField(default=1)
    color = models.CharField(max_length=200)
    wheels = models.CharField(max_length=500)

My serializer:

from rest_framework import serializers
from .models import Car


class CarSerializer(serializers.ModelSerializer):
    class Meta:
        model = Car
        fields = ['id', 'speed', 'color', 'wheels']

My view:

@api_view(['GET', 'PUT', 'DELETE'])
def car_detail_id(request, id):
    try:
        car = Car.objects.get(pk=id)
    except Car.DoesNotExist:
        #-----------------------------------------------------------#
        car = search_car(id) #fetch car from external API
        if request.method == "GET" and car is not None:
            serializer = CarSerializer(data=car)
            if serializer.is_valid():
                serializer.save()
                return Response(status=status.HTTP_201_CREATED)
        #-----------------------------------------------------------#
        return Response(status=status.HTTP_404_NOT_FOUND)
    return car_detail(request, "id", car) #method to handle CRUD

Car structure:

 {
    "speed": 1,
    "id": 1,
    "color": "Green",
    "wheels": "Black"
  },

This implementation fetch car with given ID from API, then saves it, but with different ID.
Are there any better ways to do this? Let me know below!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒与心事 2025-02-19 06:09:57

构建PK的Autofield功能需要一个唯一的标识符,并且不应/不应在DB中更改(据我所知)。

我将专注于以另一种方式完成用例。您可以使用try/除了检查对象是否存在:

try:
    ObjectName.objects.get(id=self.kwargs['id'])  # insert correct syntax for your use case
except ObjectName.DoesNotExist:
    # Make external call here

The AutoField function to build a pk requires a unique identifier and it cannot/should not be changed in the DB (as far as I am aware).

I would focus on accomplishing the use-case another way. You could use try/except to check if the object exists:

try:
    ObjectName.objects.get(id=self.kwargs['id'])  # insert correct syntax for your use case
except ObjectName.DoesNotExist:
    # Make external call here
猛虎独行 2025-02-19 06:09:57

起初:
您不需要创建自动化。 Django会自动进行。

class Post(models.Model):
    user_id = models.IntegerField(default=1)
    title = models.CharField(max_length=200)
    body = models.CharField(max_length=500)

第二:
您是“获取”的保存模型,这是不良的desigion:

  • get word读取。
  • 帖子写。

最后,尝试使用drf的视图和视图集,这很容易:

class CreatePostAPIView(CreatePostAPIView):
    model=Post

您可以每次调用此DRF视图:

def post_detail_id(request, id):
    ....    
    except Post.DoesNotExist:
            #-----------------------------------------------------------#
            request.data = request.method == "GET" and search_post(id) #fetch 
            if request.data:
                return CreatePostAPIView().post(request, *args, **kwargs)
            #-----------------------------------------------------------#
            return Response(status=status.HTTP_404_NOT_FOUND)

我的意见,post_detail_id中的某个商业逻辑被打破了。

at first:
You are dont need to create autokey. Django do it automatically.

class Post(models.Model):
    user_id = models.IntegerField(default=1)
    title = models.CharField(max_length=200)
    body = models.CharField(max_length=500)

at second:
You are save model on GET, it's bad desigion:

  • GET for read.
  • POST for write.

At last, try to use view and viewsets from DRF, it is easier:

class CreatePostAPIView(CreatePostAPIView):
    model=Post

You can call this DRF-view everythere:

def post_detail_id(request, id):
    ....    
    except Post.DoesNotExist:
            #-----------------------------------------------------------#
            request.data = request.method == "GET" and search_post(id) #fetch 
            if request.data:
                return CreatePostAPIView().post(request, *args, **kwargs)
            #-----------------------------------------------------------#
            return Response(status=status.HTTP_404_NOT_FOUND)

My opinion, somewhere business-logic in post_detail_id is broken.

德意的啸 2025-02-19 06:09:55

如果您使用serializers.modelserializer类似于上面的示例class carserializer(serializers.modelserializer):。您可以在保存时设置额外的属性。

serializer = CarSerializer(data=car)
if serializer.is_valid():
    serializer.save(id=id)

只要在模型中,您就可以添加其他属性。我找不到其他解决方案。

我从这里找到了这种方式解决方案。希望这会有所帮助

If you are using serializers.ModelSerializer like your above example class CarSerializer(serializers.ModelSerializer):. You can set extra properties while saving.

serializer = CarSerializer(data=car)
if serializer.is_valid():
    serializer.save(id=id)

You can add other properties as long as it is in the model. I can't find any other solution to do it.

I found this way from here Solution. Hope this will helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文