【问题标题】:PUT/Update Foreign Key & Many To Many relationship with just pk, and NOT the whole object放置/更新外键和多对多关系就可以了,而不是整个对象
【发布时间】:2019-04-16 15:16:27
【问题描述】:

我有一个用户模型,它有一个外键并且与另一个模型有多对多关系。

class User(AbstractUser):
    '''
    Custom User model. Countries is a list of countries associated with the
    user. Home country is a single country object
    '''
    countries = models.ManyToManyField(
        Country, blank=True, related_name='user_countries'
        )
    home = models.ForeignKey(
        Country, on_delete=models.PROTECT, null=True,
        related_name='home_country',
        )

class Country(models.Model):
    '''
    Describes the countries, as well as territories of the world.
    '''
    name = models.CharField(max_length=255, null=True, blank=True)
    top_level_domain = JSONField(null=True, blank=True)
    alpha2code = models.CharField(max_length=255, null=True, blank=True)
    alpha3code = models.CharField(max_length=255, null=True, blank=True)
    calling_codes = JSONField(null=True, blank=True)
    capital = models.CharField(max_length=255, null=True, blank=True)
    alt_spellings = JSONField(null=True, blank=True)
    region = models.CharField(max_length=255, null=True, blank=True)
    subregion = models.CharField(max_length=255, null=True, blank=True)
    population = models.IntegerField(null=True, blank=True)
    latlng = JSONField(null=True, blank=True)
    demonym = models.CharField(max_length=255, null=True, blank=True)
    area = models.FloatField(null=True, blank=True)
    gini = models.FloatField(null=True, blank=True)
    timezones = JSONField(null=True, blank=True)
    borders = JSONField(null=True, blank=True)
    native_name = models.CharField(max_length=255, null=True, blank=True)
    numeric_code= models.CharField(max_length=255, null=True, blank=True)
    currencies = models.ManyToManyField(Currency)
    languages = models.ManyToManyField(Language)
    flag = models.CharField(max_length=255, null=True, blank=True)
    regional_blocs = models.ManyToManyField(RegionalBloc, blank=True)
    cioc = models.CharField(max_length=255, null=True, blank=True)

    def __str__(self):
        return self.name

country 模型本身有几个多对多关系,因此它是一个嵌套对象。当使用 PUT 请求更新我的用户模型时,我可以序列化我的国家/地区对象以仅显示 pk,并且我可以从我的 React axios 请求中发送更新后的国家/地区的 pk,但是当我 axios GET 我的用户对象时,它只显示国家/地区。

另一方面,我可以将我的国家对象序列化为嵌套对象及其所有字段和子字段,然后我从 axios GET 请求中获取我想要的数据,但是当我想更新我的用户对象时,我有将国家对象传递给我的 axios PUT 而不仅仅是 pk。

是否可以将我的国家对象序列化为完全嵌套的美丽,但也可以通过单独传入 pk 来更新/放置我的用户模型?

我正在使用选择表单更新我的用户对象,因此很容易使用 value=pk 的选项,然后我可以只使用该值来 PUT 请求。

<option value="6">Andorra</option>

这是我目前的自定义用户详细信息序列化程序:

class UserDetailSerializer(UserDetailsSerializer):
    '''
    Custom serializer for the /rest-auth/user/ User Details Serializer.
    '''
    countries = CountrySerializer(many=True)
    home = serializers.SlugRelatedField(slug_field='pk', queryset=Country.objects.all())

    class Meta:
        model = User
        fields = ('pk', 'username', 'email', 'countries', 'home',)

    '''
    Updates the users object in the database. The username, email, countries(a
    list of country objects) and home (country object), are set by a PUT
    request from the frontend.
    '''
    def update(self, instance, validated_data):
        country_names = [cdata['name'] for cdata in validated_data['countries']]
        countries = Country.objects.filter(name__in=country_names)
        instance.username = validated_data['username']
        instance.email = validated_data['email']
        instance.countries.set(countries)
        instance.home = validated_data['home']
        instance.save()
        return instance

我目前仅通过 pk 序列化 home 字段,就像我提到的那样,这使得 PUT 很容易,但是在 React 中我得到的用户对象有

home: 6

而不是

{
    "id": 6,
    "currencies": [
        {
            "code": "EUR",
            "name": "European Euro",
            "symbol": "€"
        }
    ],
    "languages": [
        {
            "iso639_1": "ca",
            "name": "Catalan",
            "native_name": "Català"
        }
    ],
    "regional_blocs": [],
    "name": "Andorra",
    "top_level_domain": [
        ".ad"
    ],
    "alpha2code": "AD",
    "alpha3code": "AND",
    "calling_codes": [
        "376"
    ],
    "capital": "Andorra la Vella",
    "alt_spellings": [
        "AD",
        "Principality of Andorra",
        "Principat d'Andorra"
    ],
    "region": "Europe",
    "subregion": "Southern Europe",
    "population": 78014,
    "latlng": [
        42.5,
        1.5
    ],
    "demonym": "Andorran",
    "area": 468.0,
    "gini": null,
    "timezones": [
        "UTC+01:00"
    ],
    "borders": [
        "FRA",
        "ESP"
    ],
    "native_name": "Andorra",
    "numeric_code": "020",
    "flag": "https://restcountries.eu/data/and.svg",
    "cioc": "AND"
}

【问题讨论】:

    标签: django reactjs django-rest-framework axios


    【解决方案1】:

    我能够在我的序列化程序中覆盖 to_representation 函数,类似于以下说明:Django Rest Framework receive primary key value in POST and return model object as nested serializer

    【讨论】:

      猜你喜欢
      • 2013-11-20
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 2019-10-16
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 2016-12-30
      相关资源
      最近更新 更多