Accessing a model variable in Django - django

Obviously I am new to Django, because I would assume this is relatively simple.
Lets say in my models.py I created a model "User", with two fields, a "username" and a "email" field. In a form called "UserForm", I want to access a list of all the "username"s in the "User" model. This list would then be used to populate a dropdown menu using Select.
I feel like this should be really easy, and I have been looking for some simple way to do it. I can find lots of ways that aren't all inclusive (ie filter(username = "Joe")), but I can't find one that will list all the users.
Any help would be greatly appreciated.

You're looking for a ModelChoiceField. Its queryset property can be populated from an ORM call, getting you all of the Users. Have a look at the section Creating Forms from Models in the docs for more information.
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
class Meta:
model = # Your model here
def __init__(self, *args, **kwargs):
self.fields['user'] = forms.ModelChoiceField(queryset=User.objects.all())
ForeignKey fields will be automatically shown as ModelChoiceFields, but you can always override the choices if you need.

Related

Load external data into an admin model - DJANGO

Is it possible to load external data into a field for filling in?
Example: A field with for product names. However we already have the names of the products in another location, we just need to list these products within the field in the default django admin. Using resquets.
Thank you very much for your attention.
I think what you're looking for is how to customize the Django Admin, right? Check out this page in the documentation for a more detailed explanation, but here's an example that might help:
from django.contrib import admin
from .models import *
class ProductInline(admin.TabularInline):
model = Product
extra = 0
class OrderAdmin(admin.ModelAdmin):
inlines = [ProductInline]
admin.site.register(Order, OrderAdmin)
admin.site.register(Product)
This will show all of the products attached to a particular order when viewing that order from Django Admin.
You can prepopulate/fill a field in Django Admin with external data source. I guess you have some options defined somewhere outside your Django app and use those options as input for a charfield/integer field.
You can handle filling choices in a seperate Django form or overriding ModelAdmin methods. By creating a seperate form:
filter_choices = depends on your logic for loading external data
class AdminForm(forms.ModelForm):
filter_text = forms.ChoiceField(choices = filter_choices , label="Filter By",
widget=forms.Select(), required=True)
class Meta:
model = YourModel
#admin.register(YourModel)
class YourModelAdmin(admin.ModelAdmin):
form = AdminForm
You can try the 'formfield_for_foreignkey' method of the default ModelAdmin class
Example:
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "car":
kwargs["queryset"] = Car.objects.filter(owner=request.user)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
This example (from the original docs) will populate the 'car' field with only specific values.
Pls note that this method suits a foreinKey. I'm not sure if it fits your requirements.

Using database for forms django

I have an area where teachers can put homeworks for students.
Students can see these homeworks and when they click "send homework" button. they can fill a form so Teachers can see the homeworks from admin panel.
I have class to post homework.
I have 4 fields in class to post homework.
Fields = ["student number","Deadline","Lecture","Files"]
when students posting their homeworks, I want only use 2 ["student number","files"] fields for the form and I want other fields ["deadline","Lecture"] to be filled automatically from database.
What is the best way do it?
Quoting django model clean method docs:
Model.clean() This method should be used to provide custom model validation, and to modify attributes on your model if desired. For instance, you could use it to automatically provide a value for a field, or to do validation that requires access to more than a single field.
For your scenario:
import datetime
from django.db import models
class Homeworks(models.Model):
...
def clean(self):
self.Deadline = datetime.date.today() + some delta time
self.Lecture = ...
Also, remove this 'self-filled' fields from admin form interface:
class HomeworksAdmin(admin.ModelAdmin):
fields = ["student number","Files"]

Displaying information from multiple foreign keys in the django admin

I've been having some difficulty pulling information from multiple foreign keys and getting that information to display in the django admin. I have four models: Subject, Study, Procedure, and Event. The first three are foreign keys to the last. I want information from each to display in the admin for Event as such: last_name, first_name, ssn, study_desc, procedure_desc, and event_start_time where last_name, first_name_ and ssn are located in the Subject model, study_desc is located in the Study model, procedure_desc is located in the Procedure model and event_start_time is located in the Event model.
Thus far, I've been able to have the information from the Subject model and the Event model display together through use of a Model Form, but I have been unsuccessful in getting additional information from the other two models to display with what I have now. Any suggestions, insights, or alternate methods to use would be much appreciated. The form that I used is below.
class EventForm(ModelForm):
def __init__(self, *args, **kwargs):
super(EventForm, self).__init__(*args, **kwargs)
if self.instance:
self.fields['subject'].queryset = \
Subject.objects.all().order_by('last_name')
class Meta:
model = Event
class EventAdmin(admin.ModelAdmin):
form = EventForm
search_fields = ['subject__last_name','subject__first_name','subject__ssn']
list_display = ['last_name','first_name','ssn','event_start_time']
One option to display information from related objects is to use a callable.
This is exlained in the list_display docs for Django's ModelAdmin.
Also check this question on SO for some detailed examples and discussion.

Django model manager use_for_related_fields and ModelAdmin relationships

I am having trouble getting my model manager to behave correctly when using the Admin interface. Basically, I have two models:
class Employee(models.Model):
objects = models.EmployeeManager()
username = models.CharField(max_length=45, primary_key=True)
. . .
class Eotm(models.Model): #Employee of the Month
date = models.DateField()
employee = models.ForeignKey(Employee)
. . .
And I have an EmployeeManager class that overrides the get() method, something like this:
class EmployeeManager(models.Manager):
use_for_related_fields = True
def get(self, *arguments, **keywords):
try:
return super(EmployeeManager, self).get(*arguments, **keywords)
except self.model.DoesNotExist:
#If there is no Employee matching query, try an LDAP lookup and create
#a model instance for the result, if there is one.
Basically, the idea is to have Employee objects automatically created from the information in Active Directory if they don't already exist in the database. This works well from my application code, but when I tried to create a Django admin page for the Eotm model, things weren't so nice. I replaced the default widget for ForeignKey fields with a TextInput widget so users could type a username (since username is the primary key). In theory, this should call EmployeeManager.get(username='whatever'), which would either return an Employee just like the default manager or create one and return it if one didn't already exist. The problem is, my manager is not being used.
I can't find anything in the Django documentation about using custom Manager classes and the Admin site, aside from the generic manager documentation. I did find a blog entry that talked about specifying a custom manager for ModelAdmin classes, but that doesn't really help because I don't want to change the model represented by a ModelAdmin class, but one to which it is related.
I may not be understanding what you're trying to do here, but you could use a custom Form for your Eotm model:
#admin.py
from forms import EotmAdminForm
class EotmAdmin(models.ModelAdmin):
form = EotmAdminForm
#forms.py
from django import forms
from models import Eotm, Employee
class EotmAdminForm(forms.ModelForm)
class Meta:
model = Eotm
def clean_employee(self):
username = self.cleaned_data['employee']
return Employee.get(username=username)
That, in theory, should work. I haven't tested it.

Admin Form Integration for Custom Model Fields in Django

I need a model field composed of a numeric string for a Django app I'm working on and since one doesn't exist I need to roll my own. Now I understand how "get_db_prep_value" and such work, and how to extend the Model itself (the django documentation on custom model fields is an invaluable resource.), but for the life of me I can't seem to figure out how to make the admin interface error properly based on input constraints.
How do I make the associated form field in the admin error on incorrect input?
Have a look at the Form and field validation section in the Django documentation, maybe that's what you're looking for?
You would have to make a new type of form field for your custom model field.
All you need to do is define a custom modelform which uses your new field, and then tell the admin to use that form to edit your models.
class MyModelForm(forms.ModelForm):
myfield = MyCustomField()
class Meta:
model = MyModel
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm