Models Mixin ManytoMany - python

I want to implement in django a model mixin. I have in
mixin.py:
class RightsModelRelation(models.Model):
user_link = models.ForeignKey(User, on_delete=models.CASCADE, blank=False, null=False, default=None,
related_name="%(class)s_rights_user")
right_to_view = models.BooleanField(default=True)
right_to_change = models.BooleanField(default=False)
right_to_delete = models.BooleanField(default=False)
class RightsModelMixin(models.Model):
rights_link = models.ManyToManyField(RightsModelRelation, default=None,
related_name="%(class)s_rights_link")
models.py:
class Address( RightsModelMixin,models.Model):
lastname = models.CharField(max_length=255, default="", )
firstname = models.CharField(max_length=255, default="", blank=True, null=True)
But this doesn't work. Can anyone help me implement a manytomany models mixin?

To achieve what you want you should create an abstract model. It's table will never be created you can use it just like python base class - so it matches your case. More on that in the docs

Related

django getting all objects from select

I also need the field (commentGroupDesc) from the foreign keys objects.
models.py
class commentGroup (models.Model):
commentGroup = models.CharField(_("commentGroup"), primary_key=True, max_length=255)
commentGroupDesc = models.CharField(_("commentGroupDesc"),null=True, blank=True, max_length=255)
def __str__(self):
return str(self.commentGroup)
class Meta:
ordering = ['commentGroup']
class Comment (models.Model):
commentID = models.AutoField(_("commentID"),primary_key=True)
commentUser = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
commentGroup = models.ForeignKey(commentGroup, on_delete=models.CASCADE, null=True)
commentCI = models.ForeignKey(Servicenow, on_delete=models.CASCADE, null=True)
commentText = RichTextField(_("commentText"), null=True, blank=True)
commentTableUpdated = models.CharField(_("commentTableUpdated"), null=True, blank=True, max_length=25)
def __str__(self):
return str(self.commentGroup)
class Meta:
ordering = ['commentGroup']
views.py
comment = Comment.objects.get(pk=commentID)
Here I get the commentGroup fine but I also need commentGroupDesc to put into my form.
At first, it's not a good thing to name same your model field as model name which is commentGroup kindly change field name, and run migration commands.
You can simply use chaining to get commentGroupDesc, also it's better to use get_object_or_404() so:
comment = get_object_or_404(Comment,pk=commentID)
group_desc = comment.commentGroup.commentGroupDesc
Remember to change field and model name first.

How to write a self referencing Django Model?

I have a Django model "Inspection" which has:
InspectionID (PK)
PartID
SiteID
Date
Comment
Report
Signiture
I want to be able to have a one to many relationship between the inspection ID and date. So one ID can have inspections at many dates. How would I do this? I currently have the following:
class Inspection(models.Model):
InspectionID = models.IntegerField(primary_key=True, unique=True)
PartID = models.ForeignKey('Part', on_delete=models.CASCADE)
SiteID = models.ForeignKey('Site', on_delete=models.CASCADE)
Date = models.DateField(auto_now=False, auto_now_add=False)
Comment = models.CharField(max_length=255, blank=True)
Report = models.FileField(upload_to='docs', null=True, blank=True)
Signiture = models.CharField(max_length=255, blank=True)
I thought about using models.ForeignKey but I really don't know how to implement that properly in this situation.
I want to be able to have a one to many relationship between the inspection ID and date.
You create an extra model, like:
class InspectionDate(models.Model):
inspection = models.ForeignKey(
Inspection,
on_delete=models.CASCADE,
related_name='inspectiondates'
)
date = models.DateField()
You thus can create InspectionDates for a given Inspection.
Or if you want to add extra data, it might be better to define an InspectionGroup model:
class InspectionGroup(models.Model):
pass
class Inspection(models.Model):
id = models.AutoField(primary_key=True, unique=True, db_column='InspectionId')
inspectiongroup = models.ForeignKey(InspectionGroup, on_delete=models.CASCADE, db_column='InspectionGroupId')
part = models.ForeignKey('Part', on_delete=models.CASCADE, db_column='PartId')
site = models.ForeignKey('Site', on_delete=models.CASCADE, db_column='SiteId')
date = models.DateField(db_column='Date')
comment = models.CharField(max_length=255, blank=True, db_column='CommentId')
report = models.FileField(upload_to='docs', null=True, blank=True, db_column='ReportId')
signiture = models.CharField(max_length=255, blank=True, db_column='Signature')
Note: the name of attributes are normally written in snake_case [wiki], not in PerlCase or camelCase.
you may store 'self Foriegnkey' as
class Inspection(models.Model):
InspectionID = models.IntegerField(primary_key=True, unique=True)
PartID = models.ForeignKey('Part', on_delete=models.CASCADE)
SiteID = models.ForeignKey('Site', on_delete=models.CASCADE)
Date = models.DateField(auto_now=False, auto_now_add=False)
Comment = models.CharField(max_length=255, blank=True)
Report = models.FileField(upload_to='docs', null=True, blank=True)
Signiture = models.CharField(max_length=255, blank=True)
inspection_id = models.ForeignKey('self', null=True, blank=True)

How to display multiple objects from fields in Django Admin

I am a bit stumped as to how I can add multiple access_token and items_ids in Django Admin. The models and apps involved are as follows. This is my first post so please forgive if it isn't in proper format.
Trans/models.py
class Exchange(models.Model):
created = models.DateTimeField()
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='token', on_delete=models.CASCADE)
access_token = models.CharField(max_length=300, blank=True, default='')
item_id = models.CharField(max_length=300, blank=True, default='')
request_id = models.CharField(max_length=300, blank=True, default='')
class Meta:
ordering = ('item_id',)
I have setup a userprofile section for the admin:
Users/models.py
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, verbose_name='user', related_name='profile', on_delete=models.CASCADE)
avatar_url = models.CharField(max_length=256, blank=True, null=True)
dob = models.DateField(verbose_name="dob", blank=True, null=True)
public_token = models.CharField(max_length=100, blank=True, null=True, verbose_name='public_token')
access_token = models.CharField(max_length=100, blank=True, null=True, verbose_name='access_token')
item_id = models.CharField(max_length=100, blank=True, null=True, verbose_name='item_ID')
just_signed_up = models.BooleanField(default=True)
def __str__(self):
return force_text(self.user)
class Meta():
db_table = 'user_profile'
users/forms.py
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('user', 'public_token', 'access_token', 'item_id',)
users/admin.py
class UserProfileAdmin(admin.ModelAdmin):
search_fields = ('user', 'dob', 'public_token', 'access_token', 'item_id',)
ordering = ('user',)
list_select_related = ('user',)
admin.site.register(UserProfile, UserProfileAdmin)
class UserProfileAdminInline(admin.TabularInline):
model = UserProfile
I'm really just stumped as I tried making many to many field but couldnt seem to link correctly and or the process broke when testing in a sandbox environment. Any help would be greatly appreciated! In my case I need to record multiple access_tokens and item_ids for each user.
It's a little bit confusing what you are asking...particularly the way that your data model is setup....but I'm going to make a couple of assumptions in my answer (it would be helpful to better understand what you are trying to do at a high level).
I think what you are wanting to do is to be able to configure multiple Exchange objects per user profile...in which case I would set things up this way:
1. The related_name field on the FK to the user profile in the exchange model will be how you access multiple exchanges...so in this case you probably want a pluralized name.
2. To be able to edit multiple in the Django Admin you will need to setup an InlineAdmin object.
3. The CharFields that are actually ON the UserProfile will only ever be single fields...if you want multiple then you need to move them to another related object (like the Exchange model).
4. I don't think what you want here is a ManyToMany as that would imply user's would be sharing these tokens and item ids (or Exchanges?)...but maybe that is what you want...in which case you should change the ForeignKey to UserProfile from the Exchange model to a ManyToManyField. The rest of this post assumes you don't want that.
trans/models.py
from django.db import models
from django.conf import settings
class Exchange(models.Model):
class Meta:
ordering = ('item_id', )
created = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='exchanges', on_delete=models.CASCADE)
access_token = models.CharField(max_length=300, blank=True)
item_id = models.CharField(max_length=300, blank=True)
request_id = models.CharField(max_length=300, blank=True)
users/models.py
from django.db import models
from django.conf import settings
class UserProfile(models.Model):
class Meta:
db_table = 'user_profile'
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, verbose_name='user', related_name='profile', on_delete=models.CASCADE)
avatar_url = models.CharField(max_length=256, blank=True)
dob = models.DateField(verbose_name="dob", blank=True, null=True)
public_token = models.CharField(max_length=100, blank=True, null=True)
access_token = models.CharField(max_length=100, blank=True, null=True)
item_id = models.CharField(max_length=100, blank=True, null=True)
just_signed_up = models.BooleanField(default=True)
def __str__(self):
return force_text(self.user)
users/admin.py
from django.contrib import admin
from trans.models import Exchange
from users.models import UserProfile
class ExchangeAdminInline(admin.TabularInline):
model = Exchange
class UserProfileAdmin(admin.ModelAdmin):
inlines = (ExchangeAdminInline, )
search_fields = ('user', 'dob', 'public_token', 'access_token', 'item_id', )
ordering = ('user', )
list_select_related = ('user', )
admin.site.register(UserProfile, UserProfileAdmin)
There is a lot that you can do to configure the inlines to behave how you want...but that's the basics.

Is a self-join on a model in a django app an acceptable pattern?

Apologies if this question is too subjective.
If you are planning to close this question: please comment with a suggestion for a more appropriate place to post.
I'm super new to django and python, and I'm building a test app that keeps track of employees and who their managers are.
I would like to set up the domain model so that there there is only one list of employees, any of which can be managers, and all of which can be managed by any other employee who is designated a manager.
To achieve this, I did a self-join on the Employee model and have an "is_manager" flag to keep track of who is a manager and who isn't (see model below).
Is an acceptable pattern?
I'm worried it violates a design principle I'm not considering and there's some hairy trap that I'm walking into as a noob.
Thank you very much for your time.
models.py for the app:
class OrganizationTitle(models.Model):
def __str__(self):
return "{}".format(self.organization_title_name)
organization_title_name = models.CharField(max_length=150, unique=True)
class ClassificationTitle(models.Model):
def __str__(self):
return "{}".format(self.classification_title_name)
classification_title_name = models.CharField(max_length=150, unique=True)
class WorkingTitle(models.Model):
def __str__(self):
return "{}".format(self.working_title_name)
working_title_name = models.CharField(max_length=150, unique=True)
class Category(models.Model):
def __str__(self):
return "{}".format(self.category_name)
category_name = models.CharField(max_length=150, unique=True)
class Department(models.Model):
def __str__(self):
return "{}".format(self.department_name)
department_name = models.CharField(max_length=150, unique=True)
class Employee(models.Model):
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=150)
org_title = models.ForeignKey(OrganizationTitle, blank=True, null=True, on_delete=models.SET_NULL)
manager = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
manager_email = models.EmailField(max_length=50, blank=True, null=True)
hire_date = models.DateField(blank=True, null=True)
classification_title = models.ForeignKey(ClassificationTitle, blank=True, null=True, on_delete=models.SET_NULL)
working_title = models.ForeignKey(WorkingTitle, blank=True, null=True, on_delete=models.SET_NULL)
email_address = models.EmailField(max_length=250, blank=False, unique=True,
error_messages={'unique': 'An account with this email exist.',
'required': 'Please provide an email address.'})
category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
is_substitute = models.BooleanField(default=False)
department = models.ForeignKey(Department, blank=True, null=True, on_delete=models.SET_NULL)
is_active = models.BooleanField(default=True)
is_manager = models.BooleanField(default=False)
class Meta:
ordering = ('is_active', 'last_name',)
def __str__(self):
return "{}".format(self.first_name + ' ' + self.last_name)
That's perfectly fine.
I would recommend you to specify the related_name to keep your code more explicit:
manager = models.ForeignKey(..., related_name="managed_employees")
so then you can do something like:
bob.managed_employees.all()
Also, there are 2 things I would change (not your question but still regarding the models):
1.The manager_email field is redundant. I would remove it. You already have that information at tom.manager.email_address for example.
2.There are many fields that I would simply rename to name. For example:
class OrganizationTitle(models.Model):
def __str__(self):
return u"{}".format(self.name)
name = models.CharField(max_length=150, unique=True)
No need to call it organization_title_name. That's consistent with the first_name field (not employee_first_name).
Yes, this is an acceptable pattern. This is called a "recursive relationship", or "self referential foreign keys" and is a very common usecase in realworld applications.
Here is django's example supporting this usecase

create custom role in django to employees

I have created a role model for Employee so that employee will be assigned to control
the overall app based on his/her role. I mean if the role of employee is given can_create_only, then the employee should be able to create inventory, orders, items etc and if employee is given can_create_edit_and_delete, then the employee would be like one of the admin and etc. For this I have designed the model as below but I want to know what is the best way to handle such and why?
Should I go with middleware or decorator way? Can anyone give me an example, please?
class Role(models.Model):
name = models.CharField(max_length=100, blank=False, null=False)
class Meta:
verbose_name = 'Role'
verbose_name_plural = 'Roles'
class Employee(models.Model):
office = models.ForeignKey(
OfficeSetup, blank=False, null=False, on_delete=models.CASCADE)
name = models.CharField(max_length=150, blank=False, null=False)
designation = models.ForeignKey(Designation, blank=False, null=False)
section = models.ForeignKey(DepartmentSetup, blank=True, null=True)
phone_number = models.CharField(max_length=150, blank=True, null=True)
mobile_number = models.CharField(max_length=150, blank=True, null=True)
email = models.EmailField(max_length=150, blank=False, null=False)
gender = models.CharField(
max_length=4, choices=GENDER, blank=True, null=True)
role = models.ForeignKey(Role, blank=True, null=True)
username = models.CharField(max_length=100, blank=False, null=False)
password = models.CharField(max_length=100, blank=False, null=False)
avatar = models.ImageField(
null=True, blank=True, upload_to=upload_employee_image_path)
class Meta:
verbose_name = 'Employee'
verbose_name_plural = 'Employees'
def __str__(self):
return self.name
When creating an employee by admin, the username, password and email, the admin provides will create a new user instance along with the employee
Django comes with Groups and permissions which provides all most everything you are looking for.
This may help you - How do I use Django groups and permissions?
Django documentation - https://docs.djangoproject.com/en/1.11/topics/auth/

Categories