Django admin,在添加项目表单中限制选择列表

时间:2013-10-06 08:38:00

标签: python django-admin

我有3个模型类

  1. 旅游
  2. 照片
  3. 为了能够将照片添加到游览中,用户必须注册参加游览。

    我在管理面板中尝试做什么“游览” - >“添加照片”表单只显示所选游览中列出的游客列表。

    最简单的方法是什么?

    我的模型(大部分代码都与问题无关,但我想它可以提供帮助):

    class Tourist(models.Model):
    
    REQ_FIELDS = ["pk", "name", "email", "phone_number", "facebook_id",
                  "phone_is_verified", "is_banned", "bus_id"]
    
    name = models.CharField(max_length = 200)
    email = models.EmailField()
    phone_number = models.CharField(max_length = 30,
                                    null=True,
                                    blank=True,
                                    default="")
    facebook_id = models.CharField(max_length = 255,
                                   null=True,
                                   blank=True,
                                   default="")
    phone_verification_hash = models.CharField(max_length=100,
                                               blank=True,
                                               null=True,
                                               default="")
    phone_is_verified = models.BooleanField(default = False)
    is_banned = models.BooleanField(default = False)
    backoffice_notes = models.CharField(blank=True, null=True, default="", max_length=250)
    bus = models.ForeignKey(Bus, blank = True, null = True, related_name="tourists")
    is_admin_added = models.BooleanField(default = False)
    
    creation_date = models.DateTimeField(default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0))
    modified_date = models.DateTimeField(default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0), auto_now=True)
    
    lang = models.CharField(choices =(("he", "Hebrew"), ("en", "English"),), default = "he", max_length = 100)
    
    def need_phone_verification(self):
        return bool(self.phone_number) and not self.phone_is_verified
    
    def is_phone_verified(self):
        """
        can he receive sms?
        """
        return bool(self.phone_number) and self.phone_is_verified
    
    def is_facebook_verified(self):
        return bool(self.facebook_id)
    
    def login_is_verified(self):
        """
        can he upload photos?
        """
        return not self.is_banned and \
                   (self.is_phone_verified() or self.is_facebook_verified()) or \
                   self.is_admin_added
    
    def verify_phone(self):
        ans = self.send_verification_code()
        return ans
    
    def send_verification_code( self ):
        random.seed( timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()) )
        verify_code = str( int(random.random() * 9000 + 1000))
    
        if sms_verify_send( self.phone_number, verify_code ):
            self.phone_verification_hash = hashlib.sha1(verify_code).hexdigest()
            self.save()
        else:
            raise Exception("Bad SMS Server")
        return verify_code
    
    def receive_verification_code( self, submitted_code ):
        if hashlib.sha1(submitted_code).hexdigest() == \
                self.phone_verification_hash:
    
            self.phone_is_verified = True
            self.save()
            return True
        return False
    
    def __unicode__(self):
        return u"%s (%s, %s)" % ( self.name, self.email, self.phone_number )
    
    def to_dict(self):
        obj = {}
        for field_name in self.REQ_FIELDS:
            obj[field_name] = getattr(self, field_name)
        return obj
    
    def image_name(self):
    
        hebrew_test = any(u"\u0590" <= c <= u"\u05EA" for c in self.name)
        if hebrew_test:
            # if the name is in hebrew we flip it over so it will display 
            # correctly
            self.name= self.name[::-1]
    
        ans = self.name
        if self.is_phone_verified():
            if hebrew_test:
                ans = "(%s) %s" % (self.phone_number[-4:], self.name )
            else:
                ans = "%s (%s)" % (self.name, self.phone_number[-4:] )
        return ans
    

    班级之旅(models.Model):

    REQ_FIELDS = ["pk", "title", "start_time", "end_time", "display_order",
                  "is_cancelled" ]
    
    title = models.CharField(max_length = 200)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField()
    custom_logo = models.FileField(help_text="Please use a png file",
                                   upload_to='media/tour_logo',
                                   blank=True,
                                   null=True,
                                   validators=[is_png_ext])
    display_order = models.IntegerField(choices = ((1, 'First in, First out'),
                                                   (2, 'First in, Last out'),
                                                   (3, 'Equal among users'),
                                                   (4, 'Equal among busses')))
    is_cancelled = models.BooleanField(default = False)
    
    busses = models.ManyToManyField(Bus, blank=True, null=True, related_name = "tours")
    tourists = models.ManyToManyField(Tourist, blank=True, null=True, related_name = "tours")
    tourists_to_be_informed = models.ManyToManyField(Tourist, blank=True, null=True, related_name = "tours_to_be_informed")
    transportation_company_provider = models.ForeignKey(Transportation_company, related_name = "tours")
    
    backoffice_notes = models.CharField(blank=True, null=True, default="", max_length=250)
    
    client = models.ForeignKey(Client, related_name="tours")
    
    is_album_sent = models.BooleanField("Was the Album sent", default = False)
    
    tourist_validator_mail = models.EmailField(blank=True, null=True)
    
    creation_date = models.DateTimeField(default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0))
    modified_date = models.DateTimeField(default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0), auto_now=True)
    
    def is_valid(self):
        start = self.start_time
        # now = datetime.datetime.now()
        # we us time-zone aware time
        now = timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone())
    
    
        return start < now and not self.is_album_sent and not self.is_cancelled
    
    def __unicode__(self):
        return u"%s" % self.title
    
    def to_dict(self):
        obj = {}
        for field_name in self.REQ_FIELDS:
            obj[field_name] = getattr(self, field_name)
        return obj
    
    def compare_date(self, curr ):
        """
        checks if time is before tour started ( then is with minus )
        or in the tour time ( with value 0 )
        or after ( with plus )
        """
        start = self.start_time
        end = self.end_time
        if curr < start:
            return -1
        if end < curr:
            return 1
        return 0
    
    def began_and_running(self):
        # we us time-zone aware time
        time_now = timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone())
        began_and_running = self.start_time < time_now and self.photos.count() > 4
        return began_and_running
    
    def inform(self):
        from views import contact
        if self.tourists_to_be_informed.count() > 0:
            if self.began_and_running():
                for tourist in self.tourists_to_be_informed.all():
                    contact(tourist, "joined_past_notice", self)
                    self.tourists_to_be_informed.remove(tourist)
    
    def stats(self):
        return {"id": self.id,
                "title": self.title,
                "day_count": (self.end_time - self.start_time).days,
                "photo_count": self.photos.count(),
                "photo_removed_count": self.photos.filter(is_removed=True)
                                                  .count(),
                "tourist_count": self.tourists.count()}
    
    def album_link(self, tourist_id):
        query = Tour.encode_link(self.id, tourist_id)
        relative_url = build_url("pictours_app:album", get = {"query": query})
    
        msg = "http://%s%s" % (Site.objects.get_current().domain, relative_url)
        return msg
    
    def slideshow_link(self, tourist_id):
        query = Tour.encode_link(self.id, tourist_id)
        relative_url = build_url('pictours_app:slideshow', get = {"query": query})
    
        msg = "http://%s%s" % (Site.objects.get_current().domain, relative_url)
        return msg
    
    def transportation_company(self):
        tc = self.photos.exists() and self.photos.all()[0].bus.transportation_company
        return tc
    
    def admin_link(self):
        relative_url = build_url('admin:pictours_app_touractive_change', args = (self.id,))
    
        msg = "http://%s%s" % (Site.objects.get_current().domain, relative_url)
        return msg
    
    @staticmethod
    def encode_link(tour_id, tourist_id):
        encoded = tour_id * BIG_PRIM_NUM + tourist_id
        return encoded
    
    @staticmethod
    def decode_link(query):
        int_query = query and int(query)
        pk = int_query / BIG_PRIM_NUM
        tourist_id = int_query % BIG_PRIM_NUM
        return (pk, tourist_id)
    
    def validate_album_link(self):
        return self.album_link( -1 )
    

    类照片(models.Model):

    REQ_FIELDS = ["pk", "s3_url"]
    
    s3_url = models.URLField("Photo storage url", max_length=250)
    s3_url_processed = models.ImageField("Processed photo",
                                         max_length=250,
                                         upload_to=Photo_upload_path,
                                         null = True)
    
    s3_url_album = models.ImageField("Album size photo",
                                     max_length=250,
                                     upload_to=Photo_upload_path,
                                     null = True)
    
    s3_url_thumbnail = models.ImageField("Thumbnail size photo",
                                         max_length=250,
                                         upload_to=Photo_upload_path,
                                         null = True)
    
    tour = models.ForeignKey(Tour, related_name="photos")
    
    tourist = models.ForeignKey(Tourist,
                                related_name="photos")
    
    bus = models.ForeignKey(Bus, related_name="photos")
    
    description = models.CharField("backoffice notes",
                                   max_length=250,
                                   null=True,
                                   blank=True,
                                   default="")
    
    is_featured = models.BooleanField(default = False)
    is_removed = models.BooleanField(default = False)
    tourist_removed = models.ForeignKey( Tourist,
                                         related_name="removed_photos",
                                         verbose_name="Tourist who removed photo",
                                         help_text="Valid when photo is removed",
                                         null=True,
                                         blank=True)
    
    creation_date = models.DateTimeField(
        default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0),
        editable=False)
    
    # creation_date = models.DateTimeField(
    #     default=lambda: datetime.datetime.now(pytz.timezone('US/Pacific')).replace(microsecond=0),
    #     editable=False,
    #     blank=True)
    
    
    
    modified_date = models.DateTimeField(
        default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0),
        auto_now=True)
    
    def save(self, *args, **kwargs):
        from views import handle_photo
        self.bus = self.tourist.bus
        handle_photo(self, self.tour.client)
        self.tour.inform()
        super(Photo, self).save(*args, **kwargs)  # Call the "real" save() method.
    
    def to_dict(self):
        obj = {}
        for field_name in self.REQ_FIELDS:
            obj[field_name] = getattr(self, field_name)
        return obj
    
    def __unicode__(self):
        return u"<photo>tourist: %s @tour: %s" % (self.tourist, self.tour)
    

1 个答案:

答案 0 :(得分:0)

Django管理员可以处理不同的用户权限:

https://docs.djangoproject.com/en/1.5/topics/auth/default/#permissions-and-authorization

  

不仅可以为每种类型的对象设置权限,还可以设置per   特定的对象实例。通过使用has_add_permission(),   提供了has_change_permission()和has_delete_permission()方法   通过ModelAdmin类,可以自定义权限   不同的相同类型的对象实例。