Updating inherited attributes in django model objects - python

I have troubles updating attributes that are inherited from other tables
class AgentCategory(models.Model):
""" Agent Category """
class Meta:
verbose_name_plural = "agentcategories"
name = models.CharField(max_length=200, unique=True)
description = models.TextField(blank=True)
class Agent(models.Model):
agentcategory = models.ManyToManyField(AgentCategory,null=True)
How should i go about manually updating agentcategory in Agent model? As of now i am trying out this method, however, it does not work):
property_selected.agentcategory = "api/v1/agentcategory/3"
property_selected.save()
Any ideas? Thanks!

As Agent has ManyToManyField relation with AgentCategory.
agentcategory would contain the list of entries.
you can update its entries by,
agent_cats = AgentCategory.objects.filter(...)
property_selected.agentcategory.clear()
property_selected.agentcategory = agent_cats
property_selected.agentcategory.save()

Related

Factory_boy not creating RelatedFactory in Trait

I've got a Purchase model and a PurchaseInfo model. PurchaseInfo has a foreign key to Purchase. I'm trying to modify an existing Factory for Purchase that will create PurchaseInfo at the same time using RelatedFactory since it's a reverse foreign key relationship. The only thing is that I wanted to use a Taint so that I could control the value of fields within PurchaseInfo. Normally when I create a Purchase like p = PurchaseFactory() the PurchaseInfo is created with null fields inside of it. If I create a Purchase like p = PurchaseFactory(info=True), so I can get the field modifications via the Taint, the PurchaseInfo is not created at all.
I have a feeling that putting the RelatedFactory in a Taint is not the way to go. What is the correct way to do this?
Models:
class Purchase(Model):
...
class PurchaseInfo(Model):
purchase = models.ForeignKey(Purchase, on_delete=models.CASCADE, unique=True, db_index=True)
lock = DateTimeField(null=True)
lock_by = ForeignKey(...
class PurchaseInfoFactory(DjangoModelFactory):
class Meta:
model = PurchaseInfoField
lock = None
lock_by = None
class PurchaseFactory(DjangoModelFactory):
class Meta:
model = Purchase
info = RelatedFactory(PurchaseInfoFactory,
factory_related_name='purchase')
class Params:
info = Trait(internalfield=RelatedFactory(PurchaseInfoFactory,
factory_related_name='purchase',
lock=timezone.now() - relativedelta(months=1),
lock_by=SubFactory(UserFactory, user_id=1)))
I don't like my solution, but here's what I did. I derived a secondary factory with an alternate RelatedFactory. That works.
class PurchaseFactory(DjangoModelFactory):
class Meta:
model = Purchase
info = RelatedFactory(PurchaseInfoFactory,
factory_related_name='purchase')
class InfoPurchaseFactory(DjangoModelFactory):
class Meta:
model = Purchase
info = Trait(internalfield=RelatedFactory(PurchaseInfoFactory,
factory_related_name='purchase',
lock=timezone.now() - relativedelta(months=1),
lock_by=SubFactory(UserFactory, user_id=1)))

Not sure I understand dependancy between 2 django models

I am struggling to understand django models relationship.
I have this arborescence:
A train have cars, and those cars are divided into parts. Then those parts all contains different references.
Like, for exemple, all the trains have the 6 cars, and the cars 6 parts. Each part have x reference to be associated.
I would like to use all of them in a template later on, where the user can select the train, the car and the part he worked on, then generate a table from his selections with only the references associated to the parts he selected.
It should update the train and the car (I'm trying to update a stock of elements for a company)
I dont really understand which model field give to each of them. After checking the doc, Ive done something like this but i am not convinced:
class Train(Car):
train = models.CharField(max_length=200)
id = models.CharField(primary_key='True', max_length=100)
selected = models.BooleanField()
class Meta:
abstract = True
class Car(Part):
car = models.CharField(max_length=200)
id = models.CharField(primary_key='True', max_length=100)
selected = models.BooleanField()
class Meta:
abstract = True
class Part(Reference):
part = models.CharField(max_length=200)
id = models.CharField(primary_key='True', max_length=100)
selected = models.BooleanField()
class Meta:
abstract = True
class Reference(models.Model):
reference = models.CharField(max_length=200)
id = models.CharField(primary_key='True', max_length=100)
selected = models.BooleanField()
def __str__(self):
return self.reference
Can someone please help me understand this so I can do well ? Thanks!!
1-)if you add abstract = True in your Model Meta class, your class doesn't created on database as a table. If you store data for any class, you mustn't define abstract = True.
2-)For relations, you can use models.ForeignKey . If you add a class into brackets of another class, it names: inheritance.(You can think like parent-child relation). In database management, we can use foreignkey for one-to-many relationship.
3-)In Django ORM, id field automatically generated. So you don't need to define id field.
If I understand correctly, also you want to store parts of user's selected.
So, your model can be like that:
class Train(models.Model):
name = models.CharField(max_length=200) # I think you want to save name of train
class Car(models.Model):
train = models.ForeignKey(Train,on_delete=models.Cascade)
name = models.CharField(max_length=200)
class Part(models.Model):
car = models.ForeignKey(Car,on_delete=models.Cascade)
name = models.CharField(max_length=200)
class Reference(models.Model):
part = models.ForeignKey(Part,on_delete=models.Cascade)
name = models.CharField(max_length=200)
def __str__(self):
return self.reference
#addtional table for storing user's references
class UserReference(models.Model):
user = models.ForeignKey(User,on_delete=models.Cascade)
reference = models.ForeignKey(Reference,on_delete=models.Cascade)
name = models.CharField(max_length=200)
With this definitions, you can store user's definition on UserReference table. And with Django Orm, you can access train object from UserReferenceObject.
#user_reference: UserReference object like that result of UserReference.objects.first()
user_reference.reference.part.car.train.name

Nested Relationship in Django Doesn't Work

These are my models here:
class Site(models.Model):
siteID = models.CharField(max_length=255, primary_key=True)
class EndDevice(models.Model):
class Meta:
unique_together = ("edevID", "siteID")
edevID = models.CharField(max_length=255)
siteID = models.ForeignKey(Site, related_name='endDeviceList', on_delete=models.CASCADE)
deviceCategory = models.BigIntegerField()
This is my serilaizer:
class DeviceSerializer(serializers.ModelSerializer):
class Meta:
model = EndDevice
fields = ("edevID", "siteID", "deviceCategory")
class SiteSerializer(serializers.ModelSerializer):
endDeviceList = DeviceSerializer(many = True, read_only=True)
class Meta:
model = Site
fields = ("siteID", "endDeviceList")
This is my view:
class IndividualSite(generics.RetrieveUpdateDestroyAPIView):
'''
PUT site/{siteID}/
GET site/{siteID}/
DELETE site/{siteID}/
'''
queryset = EndDevice.objects.all()
serializer_class = SiteSerializer
I am trying to get/put/delete results using this class and I am trying to get all the EndDevice instances which have same siteID. But my serialzer only shows the siteID and doesn't show the endDeviceList (which should have the instants of the model EndDevice)
The problem is quite similar to this link:django rest-farmework nested relationships.
I have been trying different ways to serialize the objects, I think this is probably the smartest way, but have been really unsucccessful. Any help will be appreciated.
The urls.py:
urlpatterns = [
urlpatterns = [path('site/<str:pk>/', IndividualSite.as_view(), name = "get-site"),]
And it is connected to the main urls.
you are using read_only field for the Foreign relationship, remove that, as read_only wont display them
class SiteSerializer(serializers.ModelSerializer):
endDeviceList = DeviceSerializer(many = True)

django model referencing object from other class

Hi there pretty new to django but considering the below models, with their relationships, how do I create a read only field for the object that is a reference to a field in another class? I've looked for a while on stackoverflow, but not sure what kind of model reference that would be.
The basic logic for this being:
I have this server rack that sites on a floor in a server room, and I'm associating it to a rack position, and row to manage power consumption and other goodies. Just for my end-user's reference I want a read only field to show them what row this rack lives in, and its derived from the rack position. I'd been fiddling around with creating a method to look it up, but can't seem to figure out the syntax or find something related on the django admin pages.
Any ideas would be super appreciated, I really could use the help as I've been staring through docs forever, and can't seem to find a relevant model reference for this.
class rack(models.Model):
class Meta:
verbose_name = "Rack"
verbose_name_plural = "Racks"
def __unicode__(self):
return str(self.position)
def row(self, obj):
return self.position.row
position = models.OneToOneField("rackposition")
row = row(position.row.row)
asstag = models.CharField("Asset Tag", max_length=200, unique=True)
rackunits = models.IntegerField("Rack Units")
class rackposition(models.Model):
class Meta:
verbose_name = "Rack Position"
verbose_name_plural = "Rack Positions"
def __unicode__(self):
return str(self.position)
position = models.CharField("Position", max_length=35, primary_key=True)
row = models.ForeignKey("row")
class row(models.Model):
class Meta:
verbose_name = "Row"
verbose_name_plural = "Rows"
def __unicode__(self):
return str(self.row) + "." + str(self.suite)
row = models.CharField("Row ID", max_length=200, unique=True)
suite = models.ForeignKey(suite, blank=False)
power_budget = models.IntegerField("Power Budget")
power_volt = models.IntegerField("Power Voltage")
dual_bus = models.BooleanField("Dual Bus", default=False)
You don't need a method. Assuming you have a rack instance called my_rack, you can get its row with my_rack.position.row.
Note, you should really follow PEP8 and use CamelCase for your class names.
If you want to see it as a readonly field in the admin, you will need to define a method either on the model or on the ModelAdmin class. For example:
class RackAdmin(admin.ModelAdmin):
model = Rack
readonly_fields = ('row',)
def row(self, obj):
return obj.position.row

Searching by related fields in django admin

I've been looking at the docs for search_fields in django admin in the attempt to allow searching of related fields.
So, here are some of my models.
# models.py
class Team(models.Model):
name = models.CharField(max_length=255)
class AgeGroup(models.Model):
group = models.CharField(max_length=255)
class Runner(models.Model):
"""
Model for the runner holding a course record.
"""
name = models.CharField(max_length=100)
agegroup = models.ForeignKey(AgeGroup)
team = models.ForeignKey(Team, blank=True, null=True)
class Result(models.Model):
"""
Model for the results of records.
"""
runner = models.ForeignKey(Runner)
year = models.IntegerField(_("Year"))
time = models.CharField(_("Time"), max_length=8)
class YearRecord(models.Model):
"""
Model for storing the course records of a year.
"""
result = models.ForeignKey(Result)
year = models.IntegerField()
What I'd like is for the YearRecord admin to be able to search for the team which a runner belongs to. However as soon as I attempt to add the Runner FK relationship to the search fields I get an error on searches; TypeError: Related Field got invalid lookup: icontains
So, here is the admin setup where I'd like to be able to search through the relationships. I'm sure this matches the docs, but am I misunderstanding something here? Can this be resolved & the result__runner be extended to the team field of the Runner model?
# admin.py
class YearRecordAdmin(admin.ModelAdmin):
model = YearRecord
list_display = ('result', 'get_agegroup', 'get_team', 'year')
search_fields = ['result__runner', 'year']
def get_team(self, obj):
return obj.result.runner.team
get_team.short_description = _("Team")
def get_agegroup(self, obj):
return obj.result.runner.agegroup
get_agegroup.short_description = _("Age group")
The documentation reads:
These fields should be some kind of text field, such as CharField or TextField.
so you should use 'result__runner__team__name'.

Categories