Nested Serializer Connects with Foreign Keys but Fields Comes Empty – django-rest-framework

Question:

I have a view that gets Product model and inside there is some fields refers to another tables(foreignkeys). So I want a nested field also a json export format. I want a export that I could see another tables referrings too

views.py

class ExportDataViewDeneme3(APIView):
    permission_classes = ()
    def post(self, request):
        model_list = ["Products"]
        # Get the foreign key id from the request
        dagRunId = request.data.get("dagRunId", None)
        data = {}
        for model_name in model_list:
            try:
                model = globals()[model_name]
                queryset = model.objects.filter(dagRunId=dagRunId)
                serializer = model.objects.filter(dagRunId=dagRunId)
                serializer = model_name + 'ExportSerializer'
                serializer = globals()[serializer](queryset, many=True)
                data[model_name] = serializer.data
            except LookupError:
                pass
        json_data = json.dumps(data, indent=4,cls=DateTimeEncoder)
        response = HttpResponse(json_data, content_type='application/json')
        response['Content-Disposition'] = 'attachment; filename="export_%s.json"'%(datetime.now())
        return response

models.py

class Products(BaseIdentifiableModel):
    name = models.CharField(max_length=255, default=None, null=True, blank=True)
    price = models.CharField(max_length=50, default=None, null=True, blank=True)
    cost = models.CharField(max_length=50, default=None, null=True, blank=True)
    manufacturer = models.CharField(max_length=100, default=None, null=True, blank=True)
    model = models.CharField(max_length=255, default=None, null=True, blank=True)
    material = models.CharField(max_length=255, default=None, null=True, blank=True)
    interior = models.CharField(max_length=255, default=None, null=True, blank=True)
    upc = models.CharField(max_length=100, default=None, null=True, blank=True)
    imageUrl = models.CharField(max_length=255, default=None, null=True, blank=True)
    isTaxed = models.BooleanField(null=True, default=None)
    stateTax = models.BooleanField(null=True, default=None)
    localTax = models.BooleanField(null=True, default=None)
    funeralHomeLocations = models.ForeignKey("death_spec.FuneralHomeLocations", models.DO_NOTHING, default=None, null=True, related_name="products_funeral_home_locations", blank=True)
    productCategory = models.ForeignKey("death_spec.ProductCategories", models.DO_NOTHING, default=None, null=True, related_name="products_product_category", blank=True)
    generalPriceList = models.ForeignKey("death_spec.GeneralPriceLists", models.DO_NOTHING, default=None, null=True, related_name="products_general_price", blank=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'products'
class GeneralPriceLists(BaseIdentifiableModel):
    funeralHomeLocations = models.ForeignKey("death_spec.FuneralHomeLocations", models.DO_NOTHING, default=None, null=True, related_name="general_price_funeral_home_locations", blank=True)
    name = models.CharField(max_length=255, default=None, null=True, blank=True)
    chartOfAccounts = models.ForeignKey("death_spec.ChartOfAccounts", models.DO_NOTHING, default=None, null=True, related_name="general_price_chart_accounts", blank=True)
    products = models.ForeignKey("death_spec.Products", models.DO_NOTHING, default=None, null=True, related_name="general_price_products", blank=True)
    packages = models.ForeignKey("death_spec.Packages", models.DO_NOTHING, default=None, null=True, related_name="general_price_packages", blank=True)
    
    def __str__(self):
        return self.name
    class Meta:
        db_table = 'generalPriceLists'
class Packages(BaseIdentifiableModel):
    name = models.CharField(max_length=255, default=None, null=True, blank=True)
    description = models.TextField(default=None, null=True, blank=True)
    price = models.CharField(max_length=50, default=None, null=True, blank=True)
    funeralHomeLocations = models.ForeignKey("death_spec.FuneralHomeLocations", models.DO_NOTHING, default=None, null=True, related_name="packages_funeral_home_locations", blank=True)
    products = models.ForeignKey("death_spec.Products", models.DO_NOTHING, default=None, null=True, related_name="packages_products", blank=True)
    generalPriceList = models.ForeignKey("death_spec.GeneralPriceLists", models.DO_NOTHING, default=None, null=True, related_name="packages_general_price", blank=True)

    class Meta:
        db_table = 'packages'

serializers.py

class ProductsExportSerializer(serializers.ModelSerializer):
    general_price_products = GeneralPriceListsSerializer()
    packages_products = PackagesSerializer()
    class Meta:
      model = Products

The final response:

{
    "Products": [
        {
            "uuid": "1e19aa29-27a9-4262-9959-d72cb7a3b48f",
            "general_price_products": {
                "sourceId": null,
                "sourceSystem": null,
                "dagRunId": null,
                "name": null,
                "funeralHomeLocations": null,
                "chartOfAccounts": null,
                "products": null,
                "packages": null
            },
            "packages_products": {
                "sourceId": null,
                "sourceSystem": null,
                "dagRunId": null,
                "name": null,
                "description": null,
                "price": null,
                "funeralHomeLocations": null,
                "products": null,
                "generalPriceList": null
            },
            "sourceId": 2,
            "sourceSystem": "Dennard",
            "dagRunId": "dennard",
            "name": "Basic Services of Funeral Director & Staff",
            "price": "1775",
            "cost": "1775",
            "manufacturer": null,
            "model": null,
            "material": null,
            "interior": null,
            "upc": null,
            "imageUrl": "",
            "isTaxed": false,
            "stateTax": null,
            "localTax": null,
            "funeralHomeLocations": null,
            "productCategory": "c3031da6d65143eb8e6a7998e81f563b",
            "generalPriceList": "61413e77fdbd439f9097d00b83467620"
        },
      fields = "__all__"

I stuck, I couldn’t get this relations. packages_products and general_price_products turns null value which is shouldn’t. What am I missing?

Asked By: Twister Joe

||

Answers:

What am I missing is that I was using related_name values which is not correct. It should be the variable that we create in models. So the old version of serializer is

class ProductsExportSerializer(serializers.ModelSerializer):
    general_price_products = GeneralPriceListsSerializer()
    packages_products = PackagesSerializer()
    class Meta:
      model = Products

But it should be like this:

class ProductsExportSerializer(serializers.ModelSerializer):
    generalPriceList = GeneralPriceListsSerializer()
    productCategory = PackagesSerializer()
    funeralHomeLocations = FuneralHomeLocationsSerializer()
    class Meta:
      model = Products
      fields = "__all__"

the variable names are come from model variable that we specifiy in model.py

Answered By: Twister Joe