简体   繁体   中英

Designing a model for vehicle entry in Django

I am looking design a simple app that logs number of vehicles that enter through a point with their details.Then generate a report of different services /vehicles / etc . I have come up with a sample model.

from django.db import models

# Create your models here.

class Service(models.Model):
    service_name = models.CharField(max_length = 60)
    timestamp = models.DateTimeField(auto_now_add = True,auto_now = False)

    def __unicode__(self):
        return self.service_name

class Place(models.Model):
    place_name = models.CharField(max_length = 120)
    state = models.CharField(max_length=60)
    timestamp = models.DateTimeField(auto_now_add = True,auto_now = False)

    def __unicode__(self):
        return self.place_name

class Connection(models.Model):
    vehicle_no = models.CharField(max_length = 15)
    service= models.ForeignKey(Service)
    source = models.ForeignKey(Place,related_name = 'source')
    destination = models.ForeignKey(Place,related_name = 'destination')
    trip_distance = models.PositiveIntegerField()
    entry_timestamp = models.DateTimeField(auto_now_add = True,auto_now = False)

    def __unicode__(self):
        return self.vehicle_no 

class GlobalOption(models.Model):
    config_option = models.CharField(max_length=120)
    value = models.CharField(max_length = 60)

Admin.py

from django.contrib import admin
from .models import Connection,Service,Place,GlobalOption
from .forms import ConnectionForm
# Register your models here.


class ConnectionAdmin(admin.ModelAdmin):
    form = ConnectionForm
    list_display = ('vehicle_no','service','source','destination','trip_distance','Connection_timestamp')
    list_filter = ['Connection_timestamp']
    search_fields = ['service__service_name','vehicle_no']

class OptionAdmin(admin.ModelAdmin):
    fields = ['config_option','value']
    list_display = ('config_option','value')

class ConnectionInline(admin.TabularInline):
    model = Connection
    extra = 1

class PlaceAdmin(admin.ModelAdmin):
    list_display = ['place_name','timestamp']
    class Meta:
        Model = Place

class ConnectionInline(admin.TabularInline):
    model = Connection
    extra = 1

class ServiceAdmin(admin.ModelAdmin):
    list_display = ['service_name','timestamp']
    class Meta:
        Model = Service
    inlines = [ConnectionInline]


admin.site.register(Connection,ConnectionAdmin)
admin.site.register(Service,ServiceAdmin)
admin.site.register(Place,PlaceAdmin)
admin.site.register(GlobalOption,OptionAdmin)

However in the Admin , Whenever i add a connection, It is possible to have same source and destination locations. I do not want that. Also how would it be possible to dynamically generate the list of choices on destinations after selecting a source ?

Since, there will only be incoming connections on this app, Would a better design decision would be to have separate models for Sources and destinations?

If you don't want the same source/destination to be selected, you could handle that in the clean() method for your form.

You could generate choices & cache them based on your source/destination models, your design looks ok, but keep in mind the option to create the separate models. I do similar to allow choices based on the values in various columns of a table;

class GetResults(forms.ModelForm):

    @staticmethod
    def get_choices(event_year):

        key = FORM_CHOICES_CACHE_KEY.format(
            year=event_year
        )
        choices = cache.get(key)

        if choices:
            return choices

        age_categories = set()
        events = set()

        for age_category, event in Result.objects.values_list('age_group', 'event').distinct():
            if age_category:
                age_categories.add(age_category)
            if event:
                events.add(event)

        age_categories = [
            (ac, ac) for ac in sorted(age_categories, key=lambda a: a.lower())
        ]
        events = [
            (e, e) for e in sorted(events, key=lambda a: a.lower())
        ]

        choices = (
            age_categories,
            events
        )

        cache.set(key, choices, FORM_CHOICES_CACHE_LENGTH)

        return choices

    def __init__(self, event_year, *args, **kwargs):

        self.event_year = event_year
        if not self.event_year:
            self.event_year = datetime.datetime.utcnow().year

        age_categories, events = self.get_choices(event_year)

        super(GetResults, self).__init__(*args, **kwargs)

        self.fields['age_group'] = forms.ChoiceField(choices=age_categories)
        self.fields['age_group'].label = _("Age category")

        self.fields['event'] = forms.ChoiceField(choices=events)
        self.fields['event'].label = _("Event")

    class Meta:
        model = Result

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM