Reputation: 200
I'm facing an issue with Django and specially the use of DoesNotExist.
In my script, I'm trying to check if 'Scraper' object exist or not, if it doesn't the object is created.
For checking if it exist or not i'm using a 'try catch Model.DoesNotExists', .get() with two parameters the first one is an IDs and the last the User object.
The issue is rising when two Scraper object has a same ids but different user's, the first one 'Scraper' is created and the second erase the first one.
try:
a = Scraper.objects.get(id_lbc=ids, user=user)
except Scraper.DoesNotExist:
a = Scraper(
id_lbc=ids,
lbc_name=title,
lbc_url=url,
lbc_image=image,
lbc_price=price,
lbc_date=date,
lbc_city=city,
lbc_price_meter=price_meter,
user=user,
token_url=token,
customer=customer,
has_phone=phone,
)
a.save()
Model
class Scraper(models.Model):
id_lbc = models.IntegerField(primary_key=True)
lbc_name = models.CharField(max_length=300)
lbc_url = models.URLField(max_length=300)
lbc_image = models.URLField(
max_length=300, default='http://****/****/nothing.jpg')
lbc_price = models.IntegerField(blank=True, null=True)
lbc_price_meter = models.IntegerField(blank=True, null=True)
lbc_city = models.CharField(max_length=300)
lbc_date = models.DateTimeField(auto_now=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
token_url = models.ForeignKey(
Url_lbc, to_field='token', on_delete=models.CASCADE)
is_emailed = models.BooleanField(default=False)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
has_phone = models.BooleanField(default=False)
def __str__(self):
return self.lbc_name
What I want is create two Scraper object with same 'ids' but different User's for example
Scraper N°1
ids = 1234567
user = Nico(object)
Scraper N°2
ids = 1234567
user = Paul(object)
I thought with the User object given, the Django query can see the difference between two Scraper object but I misunderstood something...maybe the PK in my model ?
Thanks for the help
Upvotes: 0
Views: 50
Reputation: 1343
Do not use the Scraper
directly to create the object, call instead Scraper.objects.create(...)
Upvotes: 1
Reputation: 13731
You can't do what you want with your current model design. This is because id_lbc
is set as a primary key. This means it has to be unique, you can't have two istances sharing that value. What you could do though is:
class Scraper(models.Model):
id_lbc = models.IntegerField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
...
class Meta:
unique_together = [('user', 'id_lbc')]
This will make it such that id_lbc
can have duplicates within the table as long as each value has a different user
value.
Then you should also use Scraper.objects.get_or_create
:
a, created = Scraper.objects.get_or_create(id_lbc=ids, user=user, defaults={
'lbc_name': title,
'lbc_url': url,
'lbc_image': image,
'lbc_price': price,
'lbc_date': date,
'lbc_city': city,
'lbc_price_meter': price_meter,
'token_url': token,
'customer': customer,
'has_phone': phone,
})
Upvotes: 1