Django - Unique model data - django

For example:
class CarImage(models.Model):
image = models.ForeignKey(Image)
car = models.ForeignKey(Car)
message = models.TextField()
message = 'awesome car'
for image in Image.objects.all():
for car in Car.objects.all():
if not CarImage.objects.filter(
Q(image=image),
Q(car=car),
Q(message=message),
):
carimage = CarImage()
carimage.image = image
carimage.car = car
carimage.message = message
carimage.save()
Is there a more efficient way to create unique models based on multiple fields? Would a signature field make this better? Or would Django Signals fix the problem - whenever Car, Image, message is created send signal to create CarImage?

You can add unique_together constraint in CarImage model Meta.
Sets of field names that, taken together, must be unique.
Django will ensure that whenever you create a CarImage object, set of image, car and message fields taken together are unique.
class CarImage(models.Model):
image = models.ForeignKey(Image)
car = models.ForeignKey(Car)
message = models.TextField()
class Meta:
unique_together = (('image', 'car', 'message'),) # define unique_together constraint

Related

Have each user have a model attached to them, and that model has a many to one relationship with items

I am trying to create a Django application where each User has one model attached to them ( a list of Plants ) and that model is composed of individual plants. I already know I can have the plants connected to the plant list through a many-to-one relationship using foreign key as shown down below:
class PlantList(models.Model):
plant_list_id = models.AutoField(primary_key=True)
class Plant(models.Model):
plantlist = models.ForeignKey(PlantList, on_delete = models.CASCADE)
name = models.CharField(max_length = 20)
wateringInterval = models.PositiveSmallIntegerField()
However, I want each user to have a plant list attached to them that can be displayed uniquely for each user, according to the plants that they add to their list. How would I make it so that each user has a plant list?
I was trying to have it inside the register form but couldn't figure out how to do it and I wanted each plantlist to have a unique ID so that I can add plants to it easier.
class AddNewPlant(forms.Form):
name = forms.CharField(label='Name',max_length = 20)
wateringInterval = forms.IntegerField(label='Watering Interval')
The thing is, you don't need the model PlantList.
What you should do instead is: set a ForeignKey to the User Model inside the Plant Model, and in that foreign_key set a related_name='plants'.
To access the User Model use:
from django.contrib.auth import get_user_model
code example:
class Plant(models.Model):
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name='plants')
name = models.CharField(max_length = 20)
wateringInterval = models.PositiveSmallIntegerField()
Then you can access all user's plants using:
first_user = get_user_model().objects.first().plants
Try this:
class User(models.Model):
plant_list = models.ForeignKey(PlantList, on_delete=models.CASCADE)
this is for connecting plant_list with the user. Also, you need to change the relationship between plant and plant_list, so that users can have the same plants as well like below:
class Plant(models.Model):
plantlist = models.ManyToManyField(PlantList)
that way different users can have the same plants on their plant_list and every user has only one plant_list.

How to inherit a model object instead of the model class

For some reasons, I want my Boolean Fields in my class Items(models.Model) to have a foreign key in my class ItemsGotten(models.Model). Here's my code for better understanding...
Items(models.Model):
title=models.Charfield(max_length=180)
description=models.Textfield(max_length=180)
paper=models.BooleanField(default=False, blank=True)
skin=models.BooleanField(default=False, blank=True)
ItemsGotten(models.Model):
user=models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
paperitem = models.ForeignKey(???)
skinitem = models.ForeignKey(???)```
I know that you can simply get the value of the whole model class e.g paperitem = models.ForeignKey(Items). But that's not what I want to achieve, I want to get only the object from the Items model. e.g skinitem = models.ForeignKey(Items.skin). Thanks

Tablename with ID "Some_ID" doesn't exist. Perhaps it was deleted? Django Sqlite

I have database with many tables; three of those which are interlinked via primary and foreign keys are "Vendor_Details" , "Channel_Details" and "MSO_Details"
models.py
class Vendor_Details(models.Model):
class Meta:
verbose_name_plural = "Vendor_Details"
vendor_name = models.CharField(primary_key = True,max_length=50)
mso_id = models.CharField(unique = True, max_length=20)
class Channel_Details(models.Model):
class Meta:
verbose_name_plural = "Channel_Details"
channel_id = models.CharField(primary_key = True, max_length=20)
vendor_name = models.ForeignKey(Vendor_Details, on_delete=models.CASCADE)
channel_logo = models.CharField(max_length=50)
channel_name = models.CharField(max_length=50)
class MSO_Details(models.Model):
class Meta:
verbose_name_plural = "MSO_Details"
mso_id = models.ForeignKey(Vendor_Details, on_delete=models.CASCADE)
channel_id = models.ForeignKey(Channel_Details, on_delete=models.CASCADE)
channel_number = models.PositiveIntegerField()
So,
Channel_Details is linked to Vendor_Details with vendor_name and
MSO_Details is linked with Vendor_Details and Channel_Details with mso_id and channel_id respectively.
Now, I am inside Django's Administrator's MSO_Details table and trying to click on edit icon of CHANNEL ID column i get a new window opens with message Channel_ details with ID "CH6" doesn't exist. Perhaps it was deleted? May be this is because channel_id is primary key of reference table and DB will not allow the changes? But then the message should had been something different. How can i handle this situation? I clicked on edit for CH_006 and message shows CH6. I am confused whats going on here, what is django's DB refering to here?
Note : I can very well add new CHANNEL_DETAILS after click add button.
I had this kind problem for the last two days and the problem was
1. If on adding details to a new form initially, you do not add the right field required.(I was including both text and integers to a field that was only CharField)
2.The other solution when the error came again was to delete migrations and the database itself and create a new database again(Using the same database name).
In my case, I had an existing SQLite database that I've been migration over to Django. All my entities had a UUID column as their primary key.
I had set the primary key column as django.models.UUIDField thinking that Django would support it, but it doesn't.
So I converted it to a text field with UUID as default value, it started working again.
class Model(models.Model):
# id = models.UUIDField(primary_key=True)
id = models.TextField(primary_key=True, default=uuid.uuid4)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
abstract = True

Adding a count field not in models to GET request

I have a model of Gun, and each gun has multiple Loads
What I want to do is add a Load count to the gun GET request object, but not in the model it self. So the count is done when I do the GET request, and only for the GET request if possible. Otherwise I can just make the POST load_count = 0, because there is no such field and It should not be saved.
class Gun(models.Model):
name = models.CharField(max_length=128)
class Load(models.Model):
gun = models.ForeignKey(Gun, related_name='gun')
foo = ...
Serializers:
class GunSerializer(serializers.HyperlinkedModelSerializer):
??? load_count = Field() -- reverse lookup and count loads
id = serializers.Field()
class Meta:
model = Gun
fields = ('id',"name", ???? "load_count")
class LoadSerializer(serializers.HyperlinkedModelSerializer):
id = serializers.Field()
class Meta:
model = Load
Try using an IntegerField for the set count:
class GunSerializer(serializers.HyperlinkedModelSerializer):
load_count = serializers.IntegerField(source='load_set.count')
class Meta:
model = Gun
fields = ('id', "name", "load_count")
However, you are using the related_name of gun in your Load model which I would recommend changing to loads (or just omitting and then use the default load_set and the example above will work). If you want to keep the related name of gun then define the load_count serializer field as:
load_count = serializers.IntegerField(source='gun.count')

Django form linking 2 models by many to many field

I have two models:
class Actor(models.Model):
name = models.CharField(max_length=30, unique = True)
event = models.ManyToManyField(Event, blank=True, null=True)
class Event(models.Model):
name = models.CharField(max_length=30, unique = True)
long_description = models.TextField(blank=True, null=True)
I want to create a form that allows me to identify the link between the two models when I add a new entry. This works:
class ActorForm(forms.ModelForm):
class Meta:
model = Actor
The form includes both name and event, allowing me to create a new Actor and simultaneous link it to an existing Event.
On the flipside,
class EventForm(forms.ModelForm):
class Meta:
model = Event
This form does not include an actor association. So I am only able to create a new Event. I can't simultaneously link it to an existing Actor.
I tried to create an inline formset:
EventFormSet = forms.models.inlineformset_factory(Event,
Actor,
can_delete = False,
extra = 2,
form = ActorForm)
but I get an error
<'class ctg.dtb.models.Actor'> has no ForeignKey to <'class ctg.dtb.models.Event'>
This isn't too surprising. The inlineformset worked for another set of models I had, but this is a different example. I think I'm going about it entirely wrong.
Overall question: How can I create a form that allows me to create a new Event and link it to an existing Actor?
Personally, I would put the ManyToMany on Event to begin with, but to each their own...
As for how to do it, you'd want to write a custom ModelForm (not an inline formset), let's call it EventForm. It would handle all of your event's fields and would also have a ModelChoiceField or ModelMultipleChoiceField to allow selection of the Actor(s) involved. Then in your view you would split out the processing of the Event fields and the ForeignKey/M2M field.
Make sense? alt text http://sonicloft.net/im/52