Neeko
Neeko

Reputation: 200

Why Django DoesNotExist Erase other objects?

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

Answers (2)

Wariored
Wariored

Reputation: 1343

Do not use the Scraper directly to create the object, call instead Scraper.objects.create(...)

Upvotes: 1

schillingt
schillingt

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

Related Questions