I have two separate django (version >=2.2) apps: campus and equipment.
campus
- Building
- Room
equipment (all use base class Device for common attributes)
- Camera
- Display
- Switcher
- Source
- etc.
There's a lot of foreign key nesting going on, ex. source -> switcher -> room -> building, and all that works fine. I'm able to do things like
source_list = Source.objects.filter(switcher__room_id=room_id)
with no issues.
I'm creating an API for equipment that will be using raw UDP strings, so I'm a little bit limited in how fancy it can be. My question is, can I somehow figure out what specific object is being referenced by the .id alone? I can narrow the query to the equipment app since I can figure out Building/Room based on the host IP address.
In other words, my plan is to send a string from the external device with something like 1356|True|hdmi1|whatever|123|abc|stuff|
with 1356 being the .id, and then in django efficiently figure out what equipment object 1356 is referring to. I'm good on the whole transport portion of getting the string into a django view, I just need to identify what 1356 is.
Doing something (pseudo code) like this can't be the best way:
try:
Display.objects.get(id=1356)
except:
not a display...
try:
Switcher.objects.get(id=1356)
except:
not a switcher...
try:
etc., etc., etc.
Thanks in advance for any help on what is probably a dumb question. Logan
UPDATE I was hoping that since my devices used a common base class that they would have unique ids, but I was able to get their generated ids to conflict after all, as @arulmr warned me. The solution I found definitely adds some length to the strings, but django's way of creating unique ids is as follows:
import uuid
class Device(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
That's it. You now have a 16 bit id that is realistically not going to be replicated in our lifetimes. By the time it goes out UDP it ends up having a length of 36 if that's relevant to anyone but me.
With that solved, all I had to do was:
def fb_view(request, fb):
fb = fb.split('|')
id = fb.pop(0) # pull out the id
try:
# .get() will except if there's no match,
# so I'm using that as my if/elif to match the id
Display.objects.get(id=id)
Display.objects.filter(id=id).update(
things=fb[0],
other_things=int(fb[1]),
)
# not used, just there to send a 200
return HttpResponse(id, content_type='text/plain')
except:
# match was on another device
pass
try:
Switcher.objects.get(id=id)
Switcher.objects.filter(id=id).update(
things=fb[0],
other_things=int(fb[1]),
)
return HttpResponse(id, content_type='text/plain')
except:
pass
# etc, etc
Thank you both!! I ended up with the try/except chain after all, but since the feedback handling is unique to each model it worked out fine anyway. Plus I could always move the feedback handling .update() stuff to separate functions if I wanted to clean it up.