Home > Software engineering >  populating foreign key in django
populating foreign key in django

Time:08-30

I'm creating a page that lets only admin add some assets. Each asset has a type. I have used a dropdown to select the asset_type. The selected value of asset_type gets passed into views.py but I can't get it written into the newly created asset object. Here is my models.py

class assetType(models.Model):
    title = models.CharField(max_length=150)

    @property
    def get_type(self):
        return asset.objects.filter(asset_type=self.id)

    def __str__(self):
        return f"{self.title}"

    class Meta:
        verbose_name_plural = 'Asset Types'

class asset(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, null=False)
    asset_type = models.ForeignKey('assetType', on_delete=models.CASCADE, null=True)
    asset_name = models.CharField(max_length=30, null=True) #unique=True
    location = models.CharField(max_length=30, null=True)
    brand = models.CharField(max_length=30, null=True)
    purchase_year = models.PositiveIntegerField(blank=True, null=True)
    isActive = models.BooleanField(default=True, null=True)
    currentOwner = models.ForeignKey(User, default='', null=True, on_delete=models.CASCADE)

Here is createAssetView from views.py

@user_passes_test(lambda u: u.is_superuser)
def createAssetView(request):
    assetTypeList = assetType.objects.all()  # use assetType.title
    assettype = request.POST.get('asset-type')
    assetname = request.POST.get('asset-name')
    locationn = request.POST.get('location')
    brandd = request.POST.get('brand')
    purchaseyear = request.POST.get('purchase-year')
    isActivve = request.POST.get('is-active','') == 'on'
    cuser=request.user
    context={
        "cuser":request.user,
        "asset_type_list":assetTypeList,
        "asset_type":assettype,
        "asset_name":assetname,
        "location":locationn,
        "brand":brandd,
        "purchase_year":purchaseyear,
        "isActive":isActivve,
        'iterator':range(2014,2050)
    }
    if request.method == 'POST':
        new_asset = asset()
        new_asset.asset_type_title=request.POST.get('asset-type')
        new_asset.asset_name=assetname
        new_asset.location=locationn
        new_asset.brand=brandd
        new_asset.purchase_year=purchaseyear
        new_asset.isActive=True if isActivve else False
        new_asset.currentOwner=cuser
        print(assettype) # PRINT assettype
        new_asset.save()
        return redirect('createAssets')
    
    return render(request, 'assets/createAsset.html', context)

The PRINT assettype statement prints selected asset type from the form, so the value is getting passed to the view, how should I populate the table with it? Any suggestions or help will be highly appreciated. Thanks!

CodePudding user response:

new_asset.asset_type_title=request.POST.get('asset-type')

This is the line where your problem is. You can't assign a foreign object like that, it does not automatically search for a match in another model.

You need to either provide the object to be used as a foreign key, or the object's primary key.

So we find our database entry for the selected type:

target_type = assetType.objects.get(title=assettype)
# this assumes you use unique titles for each assetType, see below

and then provide the new asset either with the object itself:

new_asset.asset_type = target_type

or its primary key:

new_asset.asset_type_id = target_type.pk

I strongly reccomend spending more time with django's documentation to strengthen your understanding of how foreign object relation is implemented in django. At least review the tutorials that focus on that.

Also consider the following:

  • The title field of the assetType model is not limited to be unique. What happens if two assetTypes with the same title are created?
  • Repetition of request.POST.get('asset-type')
  • Related