Cannot query "ABC": Must be "Image" instance - django

I came across an error message within the model.py. I would appreciate if you guys could give me some assistance on this; the following are parts of the model.py:
class WorkJob(models.Model):
id = models.AutoField(primary_key=True)
share = models.ForeignKey(FShare, on_delete=models.PROTECT)
aftId = models.ForeignKey(AftId, null=True, blank=True, on_delete=models.PROTECT)
history = HistoricalRecords()
def __str__(self):
if self.aftId:
return self.aftId.aft
else:
return str('AFT-NA')
class Image(models.Model):
id = models.AutoField(primary_key=True)
imagingJob = models.OneToOneField(WorkJob, on_delete=models.PROTECT)
md5 = models.CharField(max_length=32, null=True, blank=True)
originalCopy = models.ForeignKey(Disc, related_name='originalCopy', null=True, blank=True, on_delete=models.PROTECT)
workingCopy = models.ForeignKey(Disc, related_name='workingCopy', null=True, blank=True, on_delete=models.PROTECT)
history = HistoricalRecords()
def __str__(self):
return self.imagingJob.fileShare.identifier
class Copy(models.Model):
id = models.AutoField(primary_key=True)
image = models.ForeignKey(Image, on_delete=models.PROTECT)
disc = models.ForeignKey(Disc, on_delete=models.PROTECT, related_name='copy')
history = HistoricalRecords()
def aftId(self):
return self.image.imagingJob.aftId.aft
the next class is the one that I have problems.
class TFI(models.Model):
id = models.AutoField(primary_key=True)
createDate = models.DateTimeField(auto_now_add=True, null=True)
status = models.IntegerField(choices=STATUS_OPTIONS, default=0)
history = HistoricalRecords()
def check_third(self):
if self.status == 5:
im = 0
third_imajob = WorkJob.objects.filter(share=self.share)
for ima in third_imajob:
if Copy.objects.filter(image__exact=ima.aftId).exists():
# some code blablabla
else:
break
The line that the error message says that it is problematic is:
if Copy.objects.filter(image__exact=ima.aftId).exists():
I am not certain why is it saying that the instance must be with Image. The line clearly is extracting from class Copy and WorkJob. I did see that that the Copy.image has a foreignkey reference to class Image but I am not certain how to troubleshoot this. Thanks in advance!
EDIT: following is also a part of the code and the above code has also been added.
class AftId(models.Model):
id = models.AutoField(unique=True, primary_key=True)
aft = models.CharField(unique=True, max_length=30)
assignedTo = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT)
history = HistoricalRecords()
def __str__(self):
return self.aft

You are trying to compare some aftID instances and Image.
I can't see your aftId model but I guess it has an image foreign key field, so your query should be Copy.objects.filter(image__exact=ima.aftId.image).exists()

Related

Is there a way to update top level relationship in Django form?

I have below models and form.
Brand > Section > Category > Article.
I can pull the existing data out of the database however I have hit a wall. I am trying to create a new article or update an existing article but I'm not sure how I can update the brand, then the Section. The Category I can update and it is connected directly to the Article model. I have been thinking about this for a few days now and tried different models but ultimately i can't think of the best way to connect the models and have them update in the model.
class Brand(models.Model):
def brand_image(instance, filename):
return 'uploads/brand/{0}/{1}'.format(instance.title, filename)
title = models.CharField(max_length=50, unique=True, blank=True, null=True)
image = models.ImageField(upload_to=brand_image, null=True, blank=True)
slug = AutoSlugField(populate_from='title', unique_with='title', blank=True, null=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('brand-list', kwargs={'brand_slug': self.slug})
class Section(models.Model):
title = models.CharField(max_length=50,unique=True, blank=True,null=True)
slug = AutoSlugField(populate_from='title', unique_with='title',blank=True,null=True)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='section', blank=False, null=False)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('section-list', kwargs={'section_slug': self.slug})
class Category(models.Model):
title = models.CharField(max_length=50, blank=True,null=True)
slug = AutoSlugField(populate_from='title', unique_with='title',blank=True,null=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
section = models.ForeignKey(Section, on_delete=models.CASCADE,related_name='category', blank=False ,null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('category-list', kwargs={'category_slug': self.slug})
class Article(models.Model):
title = models.CharField(max_length=100, unique=True, db_index=True)
description = models.CharField(max_length=100, blank=True, null=False)
category = models.ForeignKey(Category, on_delete=PROTECT, related_name='article', null=False, default=1)
slug = AutoSlugField(populate_from='title', unique_with='created__month')
content = HTMLField(null=True,blank=True)
internal = models.BooleanField(default=False)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default='Draft')
author = models.ForeignKey(User, related_name='author' ,on_delete=PROTECT,null=True)
updated_by = models.ForeignKey(User, related_name='updated_by',on_delete=PROTECT,null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
video = models.FileField(blank=True, null=True, upload_to='articles/videos')
favourites = models.ManyToManyField(User, related_name='art_favourite', default=None, blank=True)
tags = TaggableManager(related_name='tags', help_text='Comma or space separated list', blank=True)
pinned = models.BooleanField(default=False)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse('articles-detail', kwargs={'article_slug': self.slug})
class ArticleForm(forms.ModelForm):
title = forms.CharField(label='Article Title', max_length=100,)
description = forms.CharField(label='Description', max_length=100,required=False)
content = forms.CharField(label='Article Content',widget=CKEditorUploadingWidget(attrs={'cols': 80, 'rows': 30}))
video = forms.FileField(help_text="Valid file Extension - .mp4", required=False, validators=[validate_file_extension])
category = GroupedModelChoiceField(queryset=Category.objects.exclude(section=None).order_by('section'),choices_groupby='section')
internal = forms.BooleanField(required=False, help_text='Is this for internal use only?', label='Internal Article')
class Meta:
model = Article
exclude = ['slug','author','created','updated','updated_by','favourites','votes','views','section']
widgets = {"tags": TagWidget(attrs={"data-role": "tagsinput"})}
Any help or guidance would be greatly appreciated.
Your Article model has a foreign key link to Section for some reason. However your stated heirarchy and models use the following one-to-many relations, which creates a direct link up the chain.
Brand < Section < Category < Article.
This means that by choosing the Category you could also choose Brand and Section. If your Article had a foreign key link to Category instead, then all the information above about groups above Article could be obtained via the article, eg, article.category__section__brand. Changing the category would, by default, update section and brand. You could do this in a single dropdown that contained Category.objects.all - perhaps with the dropdown option text also containing brand and section info for clarity and sorting purposes.

Error for my model with ManyToManyField in Django

I am working for a personal project that is using an API and having user authentication with JWT (but used in serializer). I wanted to implement ManyToManyField for user and city but it doesn't work properly. This is the extended model I have found and django aggregation . I want that the UserSearchLocation to store the City and when logged in to see the city, while other users will not see it until the search same city.
models.py
class UserSearchLocation(models.Model):
city_name = models.CharField(max_length=85, blank=False)
def __str__(self):
return self.city_name
class City(models.Model):
user_searched_locations = models.ManyToManyField(User,
through='UsersLocations',
through_fields=('city', 'user'),
related_name="my_cities",
blank=True)
id = models.AutoField(primary_key=True, editable=False)
location = models.CharField(max_length=85)
country = models.CharField(max_length=85, blank=True)
country_code = models.CharField(max_length=2, blank=True)
latitude = models.DecimalField(max_digits=6, decimal_places=4,
null=True, blank=True)
longitude = models.DecimalField(max_digits=6, decimal_places=4,
null=True, blank=True)
zip_code = models.PositiveIntegerField(default=0)
#users_location = models.ManyToManyField(UserSearchLocation)
def __str__(self):
return f'{self.location}, {self.country_code}'
def save(self, *args, **kwargs):
self.location = self.location.capitalize()
self.country = self.country.capitalize()
self.country_code = self.country_code.capitalize()
return super(City, self).save(*args, **kwargs)
class Meta:
verbose_name_plural = 'cities'
unique_together = ("location", "country_code")
class UsersLocations(models.Model):
id = models.AutoField(primary_key=True, editable=False)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
city = models.ForeignKey(City,
on_delete=models.CASCADE,
related_name='locations_by_users',
null=True)
To add in localhost/admin/ a City works, but when to add a UserSearchLocation I have this error:
Exception Value:
column base_usersearchlocation.user_id does not exist
LINE 1: SELECT "base_usersearchlocation"."user_id", "base_usersearch...
Your error says the city.location doesn't exist - location is a CharField on your City model - are you sure you've run migrations and don't have any naming conflicts?

How get information from three different tables at once?

I have following models:
class Device(models.Model):
name = models.CharField(max_length=100, blank=False)
description = models.TextField(max_length=500, blank=True)
ip_address = models.GenericIPAddressField(blank=True, null=True)
contact_person = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
team = models.ForeignKey(Team, on_delete=models.SET_NULL, null=True)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.name
class TimeSlot(models.Model):
name = models.CharField(max_length=20)
start_slot = models.CharField(max_length=10)
end_slot = models.CharField(max_length=10)
def __str__(self):
return self.name
class Reservation(models.Model):
device = models.ForeignKey(Device, on_delete=models.CASCADE)
time_slot = models.ForeignKey(TimeSlot, on_delete=models.CASCADE)
date_of_reservation = models.DateField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return "{} - {} for device: {} by {}.".format(self.time_slot, self.date_of_reservation, self.device, self.user)
class ForbiddenSlot(models.Model):
device = models.ForeignKey(Device, on_delete=models.CASCADE)
time_slot = models.ForeignKey(TimeSlot, on_delete=models.CASCADE)
def __str__(self):
return str(self.time_slot)
This is simple reservation system. I have problem to understand how create query for three different tables.
I want get all TimeSlots which are not set in ForbiddenSlot and Reservation for given Device name.
I'm not entirely sure if this will work, but I think it will and is definitely worth a shot.
TimeSlot.objects.filter(
forbiddenslot__isnull=True,
reservation__device__name='Device Name',
)
It's not necessarily the easiest thing for me to wrap my head around, but not only does TimeSlot have access to .forbiddenslot_set, it also can filter by forbiddenslot. The same goes for reservation.
I guess changing the structure of your models will be much better, like deleting the model ForbiddenSlot and replacing it with a flag on the reservation model, then you can select all TimeSlots from the reservation model where the forbidden flag is False, like:
reservations = Reservation.objects.only('time_slot').filter(device__name=name_of_the_device,forbidden=False) where forbidden is a boolean field.
Using select_related() will pre-populate the appropriate attributes:
Model.objects.select_related()

How i can change my query to work in django?

I want to make a request from two tables at once, I registered dependencies in the class. But the request does not work for me. What is wrong with him?
views.py
def payments(request):
paymentsss = Transaction.objects.select_related("currency_id")[:5]
return render(request, "payments.html", {"paymentsss": paymentsss})
models.py
class Transaction(models.Model):
id = models.BigIntegerField(blank=True, null=False, primary_key=True)
currency_id = models.ForeignKey(Currency, null=True, on_delete=models.CASCADE)
deal_id = models.ForeignKey(Deal, null=True, related_name='deal', on_delete=models.CASCADE)
service_instance_id = models.ForeignKey(ServiceInstance, null=True, related_name='service_instance', on_delete=models.CASCADE)
payment_source_id = models.ForeignKey(PayerPaymentSource, null=True, related_name='payment_source', on_delete=models.CASCADE)
payment_date = models.DateTimeField(blank=True, null=True)
amount = models.IntegerField(blank=True, null=True)
status = models.CharField(max_length=255, blank=True, null=True)
context = models.TextField(blank=True, null=True) # This field type is a guess.
class Meta:
managed = False
db_table = '"processing"."transaction"'`enter code here`
And Currency for example:
class Currency(models.Model):
id = models.SmallIntegerField(blank=True, null=False, primary_key=True)
name = models.CharField(max_length=128, blank=True, null=True)
iso_name = models.CharField(max_length=3, blank=True, null=True)
minor_unit = models.SmallIntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = '"processing"."currency"'
My Error:
I would be glad if there is an example of how to make a larger request. From 3-4 tables.
Change the db_table
class Meta:
managed = False
db_table = 'processing.transaction'
class Meta:
managed = False
db_table = 'processing.currency'
You need to change the column names for the foreign keys: e.g. currency = ForeignKey(...) and deal = ForeignKey(...).
The field is a reference to the object itself, not to the id of the object. You can see that behind the scenes, Django queries using currency_id_id which doesn't make sense.
If your column name is currency_id (in your database), then your field name should be currency.

Update existing M2M relationship in Django

I'm trying to save an existing instance of a customer record. Its model has a M2M to the vehicle model (since a customer can multiple vehicles). After reading several questions/answer here, I still do not know how to solve this.
Customer model:
class Customer(models.Model):
vehicle_id = models.ManyToManyField(VehicleSale)
name = models.CharField(max_length=40, blank=True, db_index=True, null=True,
verbose_name='name')
lic = models.CharField(max_length=20, blank=True, db_index=True, null=True,
verbose_name='license')
addr = models.CharField(max_length=40, blank=True, null=True, verbose_name='address')
city = models.CharField(max_length=15, blank=True, null=True, verbose_name='city')
state = models.CharField(max_length=2, blank=True, null=True, verbose_name='state')
zip = models.CharField(max_length=10, blank=True, null=True, verbose_name='zipcode')
email = models.EmailField(blank=True, null=True, verbose_name='email')
tel1 = models.CharField(max_length=15, blank=True, verbose_name='Tel. 1', null=True)
tel2 = models.CharField(max_length=15, blank=True, verbose_name='Tel. 2', null=True)
ssn = models.CharField(max_length=12, blank=True, db_index=True, null=True,verbose_name='SSN')
class Meta:
db_table = 'customer'
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
self.name = self.name.upper()
self.addr = self.addr.upper()
self.city = self.city.upper()
self.state = self.state.upper()
return super(Customer, self).save(*args, **kwargs)
In the view, after defining customer as
customer = current_vehicle.customer_set.all()
I tried the following:
if 'customer' in request.POST:
if customer:
customer_form = CustomerForm(request.POST, instance=customer[0])
if customer_form.is_valid():
customer_form.save()
Also tried adding before customer_form is defined:
customer.vehicle_id = current_vehicle.id
And then this after the form:
customer_form.vehicle_id = current_vehicle.id
Form is not valid so it's not saved. Upon checking {{ form.errors}}, it always reports vehicle_id is required.
Finally, after the answer in this, I adjusted it to my scenario by adding:
obj = customer_form.save(commit=False)
and hoping to assign vehicle_id, but it fails immediately.
What am I missing?
Thanks.
1st EDIT:
The section on the view now looks as:
customer_form = CustomerForm(request.POST, instance=customer[0])
customer_form.save()
customer_form.vehicle_id.add(current_vehicle)
You are misunderstanding what a ManyToMany field is here:
customer_form.vehicle_id = current_vehicle.id
vehicle_id is defined as a ManyToMany field on your Customer model, therefore you can't just assign a single id to it. You have to add an instance of VehicleSale model, eg:
customer_form.vehicle_id.add(current_vehicle)
See docs here:
https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/
See also this answer for why you can't save until you populate the vehicle_id relation:
https://stackoverflow.com/a/2529875/202168