Контакт с дополнительными зависимостями (C#)

  1. Списки переменных, также известные как many-one отношения, обычно обрабатываются путем создания отдельной модели для многих и, в той модели, использования ForeignKey для "того".

  2. нет приложения как это в django.contrib, но существует несколько внешних проектов, которые можно использовать, например, django-photologue, который даже имеет некоторую поддержку просмотра изображений в администраторе.

  3. администраторский сайт не может быть сделан "пользовательским доказательством", это должно только использоваться доверяемыми пользователями. Учитывая это, способ сделать Ваш администраторский сайт достойным состоял бы в том, чтобы определить ModelAdmin для Вашего свойства и затем встроить фотографии ( встроенная документация ).

  4. Так, чтобы дать Вам некоторые быстрые проекты, все выглядело бы примерно так:

    # models.py
    class Property(models.Model):
        address = models.TextField()
        ...
    
    class PropertyImage(models.Model):
        property = models.ForeignKey(Property, related_name='images')
        image = models.ImageField()
    

    и:

    # admin.py
    class PropertyImageInline(admin.TabularInline):
        model = PropertyImage
        extra = 3
    
    class PropertyAdmin(admin.ModelAdmin):
        inlines = [ PropertyImageInline, ]
    
    admin.site.register(Property, PropertyAdmin)
    

    причиной использования related_name аргумента на ForeignKey являются так Ваши запросы, будет более читаемым, например, в этом случае можно сделать что-то вроде этого в представлении:

    property = Property.objects.get(pk=1)
    image_list = property.images.all()
    

    РЕДАКТИРОВАНИЕ: забыл упоминать, можно затем реализовать упорядочивание перетаскивания в администраторе, использующем отрывок Simon Willison Упорядочиваемый, встраивает перетаскивание использования с jQuery UI

11
задан bluish 20 May 2016 в 07:40
поделиться

3 ответа

Самый безопасный способ (т.е. самый простой способ не допустить ошибки в вашем приложении) может заключаться в следующем.

Создайте интерфейс, который абстрагирует ваше использование TFS, например:

interface ITfs
{
  bool checkout(string filename);
}

Напишите класс, реализующий этот интерфейс с использованием TFS:

class Tfs : ITfs
{
  public bool checkout(string filename)
  {
    ... code here which uses the TFS assembly ...
  }
}

Напишите другой класс, реализующий этот интерфейс без использования TFS:

class NoTfs : ITfs
{
  public bool checkout(string filename)
  {
    //TFS not installed so checking out is impossible
    return false;
  }
}

Создайте где-нибудь синглтон:

static class TfsFactory
{
  public static ITfs instance;

  static TfsFactory()
  {
    ... code here to set the instance
    either to an instance of the Tfs class
    or to an instance of the NoTfs class ...
  }
}

Теперь есть только одно место, с которым нужно быть осторожным (например, TfsFactory конструктор); остальная часть вашего кода может вызывать методы ITfs вашего TfsFactory.instance, не зная, установлена ​​ли TFS.


Чтобы ответить на последние комментарии ниже:

Согласно моим тестам (я не знаю, является ли это «определенным поведением» ') возникает исключение, когда (как только) вы вызываете метод, который зависит от отсутствующей сборки. Поэтому это ' Важно инкапсулировать ваш код-который-зависит-от-отсутствующей-сборки по крайней мере в отдельный метод (или отдельный класс) в вашей сборке.

Например, следующее не загружается, если сборка Talk отсутствует:

using System;
using OptionalLibrary;

namespace TestReferences
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            if (args.Length > 0 && args[0] == "1") {
                Talk talk = new Talk();
                Console.WriteLine(talk.sayHello() + " " + talk.sayWorld() + "!");
            } else {
                Console.WriteLine("2 Hello World!");
            }
        }
    }
}

Будет загружено следующее:

using System;
using OptionalLibrary;

namespace TestReferences
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            if (args.Length > 0 && args[0] == "1") {
                foo();
            } else {
                Console.WriteLine("2 Hello World!");
            }
        }

        static void foo()
        {
            Talk talk = new Talk();
            Console.WriteLine(talk.sayHello() + " " + talk.sayWorld() + "!");
        }
    }
}

Это результаты теста (с использованием MSVC # 2010 и .NET в Windows):

C:\github\TestReferences\TestReferences\TestReferences\bin\Debug>TestReferences.exe
2 Hello World!

C:\github\TestReferences\TestReferences\TestReferences\bin\Debug>TestReferences.exe 1

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'OptionalLibrary, Version=1.0.0.0,
 Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
   at TestReferences.MainClass.foo()
   at TestReferences.MainClass.Main(String[] args) in C:\github\TestReferences\TestReferences\TestReferences\Program.cs:
line 11

C:\github\TestReferences\TestReferences\TestReferences\bin\Debug>
6
ответ дан 3 December 2019 в 11:04
поделиться

Идея «плагина» может быть подходящим вариантом, и она также может позволить вам (позже) расширить свой приложение для работы с продуктами, отличными от TFS, если это необходимо. Вариант 2a будет таким же «рискованным» (сбой при отсутствии связанных файлов), как вариант 1.

Вы можете создать сборку с необходимыми интерфейсами для вашей конкретной цели и ссылаться на эту сборку как из вашего приложения, так и из " Плагин TFS ". Последний затем предоставляет реализации ваших интерфейсов и использует TFS для выполнения операций.

0
ответ дан 3 December 2019 в 11:04
поделиться
1
ответ дан 3 December 2019 в 11:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: