Как сделать, чтобы значение, отличное от pk, было значением, с помощью которого выполняется post-запрос в django rest framework

#django #django-rest-framework

#django #django-rest-framework

Вопрос:

Как указано в вопросе, я хотел бы иметь возможность вместо того, чтобы передавать PK внутри моего запроса JSON в запросе post, я мог бы передать другое значение, например, имя пользователя «bob» вместо 1. таким образом, идея заключается в том, что вместо моего запроса, содержащего:

 {
    "client": 1,
    "urgent": true,
    "article": 1,
    "quantity": 1,
    "order_to": 1
}
 

оно должно содержать:

 {
    "client": "bob",
    "urgent": true,
    "article": 234,
    "quantity": 1,
    "order_to": 1
}
 

вот мои соответствующие модели:

 class UserModel(models.Model):
    MEMBERSHIP_TYPE = [
    ('NM', 'NORMAL'),
    ('PT', 'PLATA'),
    ('OR', 'ORO'),
    ('PL', 'PLATINO'),
]
    id = models.AutoField(primary_key=True)
    username = models.CharField(max_length=100, unique=True)
    photo = models.ImageField(upload_to='images/', blank=True)
    address = models.TextField()
    client_type = models.CharField(max_length=2,
        choices=MEMBERSHIP_TYPE,
        default= 'NM')

    def __unicode__(self):
        return self.name

class ArticleModel(models.Model):
    id = models.AutoField(primary_key=True)
    code = models.IntegerField(unique=True)
    description = models.TextField()
    
    def __str__(self):
        return str(self.code)

class SupplierModel(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)
    address = models.TextField()
    articles = models.ManyToManyField(ArticleModel)
    def __str__(self):
        return self.name

class OrderModel(models.Model):
    id = models.AutoField(primary_key=True)
    client = models.ForeignKey('UserModel', on_delete=models.CASCADE)
    gen_time = models.DateTimeField(auto_now_add=True)
    gen_supplied = models.DateTimeField(null=True, blank=True)
    urgent = models.BooleanField()
    order_to = models.ForeignKey('OrderToModel', on_delete=models.CASCADE)
    article = models.ForeignKey('ArticleModel', on_delete=models.CASCADE)
    quantity= models.IntegerField()
 

и сериализатор:

 class OrderCreateSerializer(serializers.ModelSerializer):

    # order_to = OrderToPolymorphicSerializer()
    class Meta:
        model = OrderModel
        fields = ('client', 'urgent', 'article', 'quantity', 'order_to')
 

Помощь очень ценится.
Заранее благодарю вас.

Комментарии:

1. Это может быть возможно с использованием SlugRelatedField django-rest-framework.org/api-guide/relations/#slugrelatedfield

2. Я не совсем понимаю, как это сделать. Не могли бы вы уточнить?

Ответ №1:

вы можете сделать это

 
class OrderCreateSerializer(serializers.ModelSerializer):
    client = serializers.SlugRelatedField(
        slug_field='username',
        queryset=UserModel.objects.all()
    )
    article = serializers.SlugRelatedField(
        slug_field='code',
        queryset=ArticleModel.objects.all()
    )

    class Meta:
        model = OrderModel
        fields = ('client', 'urgent', 'article', 'quantity', 'order_to')
 

Комментарии:

1. OP хотел иметь возможность записывать в поля сериализатора, не думаю read_only=True , что это сработает, плюс slug_field для клиента должно быть username

2. Что я хочу сделать, так это иметь возможность отправлять запрос, используя «username» вместо PK Id, это не совсем то, что я ищу.

3. @paula.em.lafon попробуйте внести правку, которую я сделал, думаю, это должно сработать…

4. спасибо за обновление, я забыл удалить только для чтения, потому что я только что проснулся и не ел

5. @paula.em.lafon итак, я думаю, вы бы передали queryset=UserModel.objects.all() client поле и аналогичный параметр article полю