0

I am new to Django and Python. Let's say I am building an app to manage devices used by users in companies. I have multiple companies, with multiple users and rooms in each.

Rooms and users are always linked to a company.

A device can be linked to:

  • An user ("Joe's iPhone", "Anna's Laptop")
  • A room ("Conference Room's Computer")

A device is always linked to a company.

So, I can have a device, that is linked to a company only.

So here's my code :

models.py:

class Company(models.Model):
    name=models.CharField(max_length=50)

class User(models.Model):
    name=models.CharField(max_length=50)
    company=models.ForeignKey('Company', on_delete=models.CASCADE)

class Room(models.Model):
    name=models.CharField(max_length=50)
    company=models.ForeignKey('Company', on_delete=models.CASCADE)

class Device(models.Model):
    company=models.ForeignKey('Company', on_delete=models.CASCADE)
    user=models.ForeignKey('User', on_delete=models.CASCADE,  blank=True, null=True)
     room=models.ForeignKey('Room', on_delete=models.CASCADE,  blank=True, null=True)

admin.py:

class DevicesInline(admin.TabularInline):
    model = Device
    extra = 0
    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        if db_field == "Company":
            kwargs['queryset'] = ## Here I don't know ##
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

class UserAdmin(admin.ModelAdmin):
    inlines = [DeviceInline]

What I want is pretty simple : when I am editing a user (or a room), I want to be able to add a device for it. But the field Company has to be filled with the company for the user or room, and it can't be modified. That's all :)

PS: I don't know if the device needs to be linked to the company if it's already linked to a user or room ? That's a whole other question.

Ahtisham
  • 9,170
  • 4
  • 43
  • 57
vjuluss
  • 31
  • 2

2 Answers2

0

In Django , to mark a field required you must add the the kwarg blank blank=False to the field , as well as adding null=False to enforce the relation on the database. In your case if you want to force the user to add a company:

class User(models.Model):
    name=models.CharField(max_length=50)
    company=models.ForeignKey('Company',blank=False,null=False, on_delete=models.CASCADE)

class Room(models.Model):
    name=models.CharField(max_length=50)
    company=models.ForeignKey('Company',blank=False,null=False, on_delete=models.CASCADE)

Moreover,no need to add Company as ForeignKey inside the Device model,your data will not be accurate , suppose that the device is linked to CompanyA while the device room is linked to CompanyB...

With respect to making the Company a readonly field, have a look at this answer.

class MyModelAdmin(admin.ModelAdmin):

    def get_readonly_fields(self, request, obj=None):
        if obj: # editing an existing object
            return self.readonly_fields + ('field1', 'field2')
        return self.readonly_fields
Haidar Zeineddine
  • 979
  • 1
  • 8
  • 20
0

I did not have time this week to work on this, but I tought about it.

A device will be linked to a company, a user or a room. It has to be linked to one of them. So if a device is linked to a user, as user are linked to a company, therefore the device is linked to the company of the user.

Now I just have to do something inside the model to say that a device must have a company, a user or a room. I don't know how I will do that yet.

vjuluss
  • 31
  • 2