Django models use id group as ForeignKey - django

I am developing one site and need to link table records to group id so I wrote my model for db but when I try to insert foreignkey i receive errors on makemigrations:
(fields.E300) Field defines a relation with model 'Group', which is either not installed, or is abstract.
and
sito_boe.Boe.group_id: (fields.E307) The field sito_boe.Boe.group_id was declared with a lazy reference to 'sito_boe.group', but app 'sito_boe' doesn't provide model 'group'
Here is my model.
I just searched on web and documentation without luck, Anyone can help me?
Here is my code:
from django.contrib.auth.models import Group
#Group.auth_group
class Boe(models.Model):
"""Model representing an author."""
Name = models.CharField(max_length=100,verbose_name="Nome")
Geo_POS = models.CharField(max_length=100,verbose_name="Coordinate")
Luogo = models.TextField(verbose_name="Posizione")
created_date = models.DateTimeField(default=timezone.now)
#group_id = models.CharField(max_length=100,verbose_name="Gruppo")
id_boa = models.CharField(max_length=20,unique=True,blank=False,verbose_name="Identificativo boa",help_text='Enter field boaXX')
group_id = models.ForeignKey('Group.auth_group', on_delete=models.SET_NULL, null=True)
def __str__(self):
"""String for representing the Model object."""
return self.Name
class Meta:
ordering = ['Name']
verbose_name_plural = "Boe"
def get_absolute_url(self):
"""Returns the url to access a particular author instance."""
return reverse('listaboe', args=[str(self.id)])

If you need to have a foreign key to Group, you can add something like:
group = models.ForeignKey(Group, related_name="boes", on_delete=models.SET_NULL)
Currently, you are using "Group.auth_group" rather than Group in your group related foreign key field.

Related

Django Model advance Foreignkey Relation

I have a Django model which has relationship with user model. Where user are assigned to groups. especially "Admin", "Teacher","Student". So I want to make a foreign key relationship in such a way that it will show only The users that have been assigned to Teacher groups for Teacher_details model, And Similar for Student_Details Model. I have made the models Teacher_Details , Student_Details and established foreign key relation with User model. But the problem is that its showing all the user when I am filling Student_Details or Teacher_Details. Hope you got my problem.
I am hoping positive response.
The code looks like this:
class Student_Details(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
image = models.ImageField(default='none', upload_to='img/')
details_updated = models.DateTimeField(auto_now_add=True)
address = models.CharField(max_length=150)
admission_date = models.DateField()
previous_college = models.CharField(max_length=150)
course_enrolled = models.ForeignKey(ModelUniversity,on_delete=models.CASCADE)
semester = models.CharField(max_length=20,choices=semester,default=None)
def __str__(self):
return self.user.first_name
class Teacher_Details(models.Model):
address = models.CharField(max_length=150)
image = models.ImageField(default='none', upload_to='img/')
details_updated = models.DateTimeField(auto_now_add=True)
subject_taught = models.ManyToManyField(to='Student.stu_subject')
user = models.OneToOneField(User,on_delete=models.CASCADE)
def __str__(self):
return self.user.first_name
def subject_teacher_teaches(self):
return [str(s) for s in self.subject_taught.all()]
Since both models have a user_id reference, you could use that info to search both models based on the request and fetch the necessary instance. Make a view which checks the user_id in the request, search both models and return the results (I assume a user cannot belong to both groups...)

ModelMultipleChoiceFilter - Field 'id' expected a number but got 'Diner'

So I have a simple Ad model and a FilterView showing all the ads. The ads can be filtered by different tags stored in a separate model joined by a ManyToManyField.
I'm using django-filter to set up a small ModelMultipleChoiceFilter and let users select different tags to filter the Ads. This is working however it uses the tag__id. I would like it to use the tag__slug field.
Therefore I've added the attribute "to_field_name='slug'" but I get the following;
Field 'id' expected a number but got 'diner'.
The following code does work but only filters by tag__id like:
/?tags=6
and I would rather see something like this;
?tags=diner
models.py
class Ad(models.Model):
category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True)
description = RichTextField()
tags = models.ManyToManyField('Tag')
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, null=True)
class Meta:
ordering = ['-title']
def __str__(self):
return self.title
class Tag(models.Model):
name = models.CharField(max_length=200, help_text='Titel van de tag')
slug = models.SlugField(max_length=200, null=True)
def __str__(self):
return self.name
filters.py
from django import forms
from discovery.grid.models import Ad, Tag
import django_filters
class AdFilter(django_filters.FilterSet):
tags = django_filters.ModelMultipleChoiceFilter(
# to_field_name='slug',
queryset=Tag.objects.all(),
widget=forms.CheckboxSelectMultiple)
class Meta:
model = Ad
fields = [
'tags'
]
How can I achieve filtering based on the model name or slug instead of the id?
With best regards,
Maybe you can try like this:
class AdFilter(django_filters.FilterSet):
tags = CharFilter(method='my_custom_filter')
def my_custom_filter(self, queryset, name, value):
return queryset.filter(**{
'tags__slug__iexact': value,
})
class Meta:
model = Ad
fields = [
'tags'
]
More information can be found in documentation.

django: Can not find the Data table row of the Extra field on many-to-many relationships?

Hello i am trying to understand Django Data Models and it´s possibilities. After using one-to-one and m2m i am now trying to understand the m2m extra fields. So i followed the Example of the Django Doc and populated the models with some Data.
models.py
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
So far everything is fine, but as i looked into the model tables, via pgAdmin 4 ( i am using PostgreSQL), i could not find any members column in the Group model. So i made a little visual of my model and some screenshots of pgAdmin, for better understanding.
As you can see Group has only a id and name column.
Question
my question: Is this m2m members relation of Group, only some kind of "virtual" created relation via the Membership.person.fk and Membership.group.fk? Meaning there is no field which will be populated? I try to imagine that it works like a recursive, instance query?

Django RestFramework - parent-child model serializer with DB views?

I am trying to implement a serializer that returns a parent record with its children embedded in the response json object.
My model for the parent and child are both based on database views:
class ProductContributorView(models.Model): # its a model of a view
id = models.IntegerField(primary_key=True)
product_id = models.ForeignKey('ProductTitleView', on_delete=models.DO_NOTHING, related_name='contributors')
sequenceNumber = models.IntegerField()
name = models.CharField(max_length=180)
role = models.CharField(max_length=8, null=True)
description = models.CharField(max_length=1408)
class Meta:
managed = False
ordering = ['sequenceNumber',]
class ProductTitleView(models.Model):
id = models.IntegerField(primary_key=True)
isbn = models.CharField(max_length=80)
titleText = models.CharField(max_length=300)
class Meta:
managed = False
ordering = ['titleText', 'isbn',]
Here are the serializers:
class ProductContributorViewSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ProductContributorView
fields = ('id', 'product_id', 'sequenceNumber', 'name', 'role', 'description')
def create(self, validated_data):
contributor = ProductContributorView.objects.create(
id=validated_data['id'],
product_id=validated_data['product_id'],
sequenceNumber=validated_data['sequenceNumber'],
name=validated_data['name'],
role=validated_data['role'],
description=validated_data['description'])
return contributor
class ProductTitleViewSerializer(serializers.HyperlinkedModelSerializer):
contributors = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = ProductTitleView
fields = ('id', 'isbn', 'titleText', 'contributors')
Here are the views:
class ProductTitleViewList(generics.ListAPIView):
queryset = ProductTitleView.objects.all()
serializer_class = ProductTitleViewSerializer
class ProductContributorViewList(generics.ListAPIView):
queryset = ProductContributorView.objects.all()
serializer_class = ProductContributorViewSerializer
The basic idea is to have the contributors - author, illustrator, etc - returned with the book title based on the FK in the ProductContributorView view matching the id in the ProductTitleView.
When I run this, however, I get the following error:
1054, "Unknown column 'jester_productcontributorview.product_id_id' in 'field list'"
I didn't specify product_id_id in the field list, and I've also tried referring to the field as just product in the field list, but it still repeats the _id_id suffix. Hoping someone will point me to documentation where the FK naming conventions are explained or tell me what to change in the field list. Thanks!
You may just want to try renaming that product_id ForeignKey to just product.
This hints to why it may be broken, I suspect it's breaking somewhere in the serializers inspection of your models regarding the naming of the product_id field on the model.
When you define a ForeignKey on a model there are two properties available for that field. One is the property you define, the ForeignKey object, and you should use this to get the related model. Behind the scenes Django also creates another property which appends _id to the the foreign key's name, this property represents the IntegerField on the database which stores the relation. If you were to view the table in psql you will see the _id columns (and in your case, _id_id).

Django admin Trouble saving new records with M2M fields - instance needs to have a primary key value before a many-to-many relationship can be used

Problem Statement:
I am using Django admin to manage many tables, some of which have many-to-many relationships. I am unable to save new records in tables (models) that have manytomany fields defined. I am able to render the add form just fine. The problem is only upon trying to save the record. I do not have the same problem when updating an existing record.
Using the models below, I receive the following error: 'Bout' instance needs to have a primary key value before a many-to-many relationship can be used.
The Bout model has a many-to-many relationship with the Equipment model. The BoutEquipment model is the intermediate model.
I've researched this problem high and low on StackOverflow and via Google, but am thus far unable to find a solution.
Disclosure: I'm new to Django and new-ish to Python. I'm hopeful that there's a relatively simple solution to this problem.
Thanks in advance.
models.py
class Bout(models.Model):
boutid = models.AutoField(db_column=u'BoutID', primary_key=True)
sessionid = models.ForeignKey(Session, db_column=u'SessionID', verbose_name=u'Session')
activitytypeid = models.ForeignKey(Activitytype, db_column=u'ActivityTypeID', verbose_name=u'Activity Type')
locationid = models.ForeignKey(Location, db_column=u'LocationID',verbose_name=u'Location')
equipment = models.ManyToManyField(Equipment, verbose_name=u'Related Equipment', related_name=u'Bout_Equipment', blank=True, null=True) #through = 'BoutEquipment'
intensitymetrics = models.ManyToManyField(Intensitymetric, verbose_name=u'Related Intensity Metrics', related_name=u'Bout_IntensityMetrics', blank=True, null=True) #through = 'BoutIntensitymetric'
def __unicode__(self):
return u'%s %s' % (self.sessionid, self.activitytypeid)
class Meta:
db_table = u'app_bout'
verbose_name = u'Bout'
verbose_name_plural = u'Bouts'
class Equipment(models.Model):
equipmentid = models.AutoField(db_column=u'EquipmentID', primary_key=True)
name = models.CharField("Name", max_length=100, db_column=u'Name')
equipmenttypeid = models.ForeignKey(Equipmenttype, db_column=u'EquipmentTypeID', verbose_name = u'Equipment Type')
def __unicode__(self):
return self.name
class Meta:
db_table = u'app_equipment'
verbose_name = u'Equipment'
verbose_name_plural = u'Equipment'
class BoutEquipment(models.Model):
id = models.AutoField(db_column=u'id', primary_key=True)
boutid = models.ForeignKey(Bout, db_column=u'Bout_ID')
equipmentid = models.ForeignKey(Equipment, db_column=u'Equipment_ID')
def __unicode__(self):
return self.name
class Meta:
db_table = u'app_bout_equipments'
admin.py
class EquipmentAdmin(admin.ModelAdmin):
form = EquipmentForm
inlines = [EquipmentShoeInline, EquipmentLogInline]
list_display = ('name','equipmenttypeid','manufacturer','retired','retiredby','retiredon','notes')
fields = (
'name',
('equipmenttypeid','manufacturer'),
('retired','retiredby','retiredon'),
'notes'
)
class BoutAdmin(admin.ModelAdmin):
form = BoutForm
filter_horizontal = ('equipment','intensitymetrics',)
list_display = ('sessionid','activitytypeid','locationid','sequence','activehand','baddata')
inlines = [BoutDeviceInline,]
fields = (
('sessionid','locationid','activitytypeid'),
'videofilelocation',
'sequence',
'activehand',
'notes',
'baddata',
('equipment','intensitymetrics')
)
A manytomany field in django is a join table between the two models you want to connect to each other.
This happens on SQL level, so both models have to exist in the database.
bout = Bout()
...
equipment = Equipment()
...
bout.equipment.add(equipment)
#fails because bout and equipment are not saved
bout.save()
bout.equipment.add(equipment)
#fails because equipment is not saved
equipment.save()
bout.equipment.add(equipment)
#yay :)