How to pre-fill a modelform field DJango - python

ive been searching for a while for information on how to do this.
here is my situation.
i have a ContactForm(form.ModelForm):
and it excludes the ID field
which i want to be auto generated based on the last entry to the Contact table
but im not finding any examples on how to do this
the help im lookin for is how to enter information without being visible to the user while at the same time automatically pre-fill the right id and i cant use pk cause it has a foriegn key to another table

If you define a field of a model as an AutoField it will do this exact thing
EDIT:
If you want to define a custom auto incrementing ID you can do it like:
from django.db import models
class MyModel(models.Model):
_id_counter = 0
custom_id = models.IntegerField()
#classmethod
def create(cls):
my_model = cls(custom_id=MyModel._id_counter)
MyModel._id_counter += 1
return my_model
model1 = MyModel.create()

Related

Django get field from m2m and foreign key

I am adding functionality to my django application to add models(Lot) linked to another(Job) with an M2M field.
The problem:
I am using Django autocomplete light to add this model(Lot) in the form and i want this field to also be filtered by the input and another autocomplete field(Contract), this field is an object called contract that is in the reverse of the M2M field:
Relations:
{Lot}--reverse on the M2M--{Job}--Foreign Key--{Contract}
I am trying to filter lot in the autocomplete to only those where the contract key on the order matches a field in the form, i have looked through documentation and im unsure if there is anyway to do this, below is my latest attempt along with relevant code.
models.py(only fields for the relationship)
class Contract(Parent_model):
contract_id = models.IntegerField(null=False, default=0000)
class Job(Job_parent):
contract = models.ForeignKey(Contract, on_delete=models.CASCADE)
class Lot(Job_parent):
CO = models.ManyToManyField(Job, related_name='Lot')
autocomplete class based view(views.py)
class lot_auto_complete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = Lot.objects.all()
contract_in = self.forwarded.get('contract', None)
if contract:
query_set = qs.filter(CO_set.first().contract=contract_in)
if self.q:
query_set = qs.filter(lot_number__icontains=self.q)
return query_set
Don't get me wrong I am not familiar with Django autocomplete light. But it seems that your code has slightly wrong. I think you can get what you want just by doing these:
# Just change your query
query_set = qs.objects.filter(CO__contract__contract_id__in=contract_in)
If contract_in list contain only id's. If it contains a list of the contract object then it will look like
query_set = qs.objects.filter(CO__contract__in=contract_in)

How to check if user is in a certain table

I have my user table in django, and to differ all the users I created two tables, (Teacher and Student).
Both tables are getting an fk from user
So, in order to make authorization how do I check if one's user is in a certain table.
I need to check it this way
def test_func(self):
return self.request.user.check..if..it..exists..in..table
My models are like this.
class Teacher(models.Model):
User = models.OneToOneField(settings.AUTH_USER_MODEL)
This depends on how your models are set up.
If your Teacher model looks something like this;
class Teacher(models.Model):
user = models.ForeignKey(User)
Then you should be able to check if the user is a teacher by using the implicit backref;
self.request.user.teacher_set.exists()
As the question has been updated to show that the model is slightly different than I anticipated, here is an update.
class Teacher(models.Model):
user = models.OneToOneField(User)
Which means that the backref will be a little different.
hasattr(self.request.user, "teacher")
As you've mentioned that you are doing this inside a django template, I'm pretty sure that the following will work:
{% if user.teacher %}
Since you haven't posted your models, I am giving you a rough idea how to do it.
in your views.py -
from .models import Teacher,Student
def test_func(request):
user = request.user
if (Teacher.objects.filter(user=user).count() > 0) or (Student.objects.filter(user=user).count > 0):
#do your stuffs here..
One way is to query both tables:
teacher = Teacher.objects.filter(user=self.request.user)
student = Student.objects.filter(user=self.request.user)
if teacher or student:
# do what you want.
If you put in your relation the argument "related_name" you can do it using inverse relationship
class SomeTable(models.Model):
user = models.ForeignKey(
User, #Your user model or Django one
verbose_name = "User",
related_name = "inverse_relation_name"
)
Then you have to call using keyword arguments for the filters:
SomeTable.inverse_relation_name.filter(id=self.request.user.id) #You will get a queryset
Or
SomeTable.inverse_relation_name.get(id=self.request.user.id) # You will get the object or a exception

Django admin search and edit foreign fields

I've got a two part question regarding Django Admin.
Firstly, I've got a Django model Classified that has a foreign key field from another table Address. On setting data, I've got no issues with any of the fields and all fields get saved correctly.
However, if I want to edit the foreign field in the entry in Classified, it doesn't display the old/existing data in the fields. Instead it shows empty fields in the popup that opens.
How do I get the fields to display the existing data on clicking the + so that I can edit the correct information?
Secondly, I'm sure I've seen search fields in Django Admin. Am I mistaken? Is there a way for me to implement search in the admin panel? I have over 2 million records which need to be updated deleted from time to time. It's very cumbersome to manually go through all the pages in the admin and delete or edit those.
Adding Model Code:
Classified
class Classified(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=256)
contact_person = models.CharField(max_length=300, blank=True)
email = models.CharField(max_length=100, blank=True)
address = models.ForeignKey(Address)
subcategory = models.ForeignKey(Subcategory)
Address
class Address(models.Model):
id = models.AutoField(primary_key=True)
build_add = models.CharField(max_length=255)
street_add = models.CharField(max_length=255)
area = models.CharField(max_length=255)
city = models.ForeignKey(Cities)
The + means just that - add a new instance of the related object and relate the object you're editing to that. Because you're adding a new object it will be blank to start. If you want to be able to edit existing related objects from another object's admin you need to use inlines.
In your app's admin.py have something like:
from django.contrib import admin
from yourapp.models import Address, Classified
class AddressInline(admin.TabularInline):
model = Address
class ClassifiedAdmin(admin.ModelAdmin):
inlines = [AddressInline,]
admin.site.register(Classified, ClassifiedAdmin)
Adding search from there is really easy.
...
class ClassifiedAdmin(admin.ModelAdmin):
inlines = [AddressInline,]
search_fields = [
'field_you_want_to_search',
'another_field',
'address__field_on_relation',
]
...
Note the double underscore in that last one. That means you can search based on values in related objects' fields.
EDIT: This answer is right in that your foreignkey relationship is the wrong way round to do it this way - with the models shown in your question Classified would be the inline and Address the primary model.

Is there a field in django that can have multiple foreign key fields?

Is there a field in django that can have multiple foreign key fields? I have the following code:
from django.db import models
from django.auth.models import *
class Wish(Model):
name = CharField(max_length=128)
cost = IntegerField()
person = ForeignKey(Person)
date = DateField('Date Wished')
comments = CharField(max_length=1024)
def __unicode__(self):
return name
class Person(Model):
user = ForeignKey(User)
friends =... # multiple foriegn keys of itself
Try using the ManyToMany field.
Note that ManyToMany to the same model, is assumed to be symmetrical - if Person A is a friend of Person B, then Person B will also be a friend of Person A. You can specify symmetrical=False to avoid that.
I think you want a ManyToMany field. In this example you would be saying that a person can be friends with many other person's/people, and visa-versa.
Django's ManyToManyField:
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ManyToManyField
General ManyToMany:
http://en.wikipedia.org/wiki/Many-to-many_(data_model)

Django - Need some guidance on how to implement a ManyToMany database

I want the ability to let users indicate what countries they have visited.. my models.py looks something like this:
class User(models.Model):
name = models.CharField(max_length=50)
countries = models.ManyToManyField(Countries)
class Countries(models.Model):
#This is where I don't know what to do.
#The end goal is for the user to be able to check off what countries he/she has visited
You would create the relationship the other way around
class User(models.Model):
name = models.CharField(max_length=50)
class Countries(models.Model):
user = models.ForeignKey(User)
If you are using django's built in User stuff then you only need this.
from django.contrib.auth.models import User
class Countries(models.Model):
user = models.ForeignKey(User)
Relation fields already generate an attribute on the other model for the reverse relation unless explicitly disabled.
You're fine as is w/r/t the ManyToManyField.
Now you'll want to create a form for this model to allow the checking-off to be done by your users.

Categories

Resources